Minimum steps to convert all paths in matrix from top left to bottom right as palindromic paths
Last Updated :
24 Mar, 2023
Given a matrix mat[][] with N rows and M columns. The task is to find the minimum number of changes required in the matrix such that every path from top left to bottom right is a palindromic path. In a path only right and bottom movements are allowed from one cell to another cell.
Examples:
Input: mat[][] = {{1, 2}, {3, 1}}
Output: 0
Explanation:
Every path in the matrix from top left to bottom right is palindromic.
Paths => {1, 2, 1}, {1, 3, 1}
Input: mat[][] = {{1, 2}, {3, 5}}
Output: 1
Explanation:
Only one change is required for the every path to be palindromic.
That is => mat[1][1] = 1
Paths => {1, 2, 1}, {1, 3, 1}
Simple Approach:
The key observation in the problem is that elements at the same distance from the front end or rear end are equal. Therefore, find all the elements at equal distance from (0, 0) and (N-1, M-1) and then make all of them equal in a minimum number of changes. Maintain a count variable to get the total number of changes. Below is the illustration of the approach:
- The distance possible from the top left and bottom right is 0 to N + M - 2.
- Maintain two-pointers one at the top left that is the distance at 0 and another at N + M - 2.
- Iterate over the matrix and for all distance maintain an hash-map of the elements of the matrix at the current distance.
- Update the matrix elements with the minimum number of changes required.
- Finally, increment the left distance by 1 and decrement the right distance by 1.
Below is the implementation of the above approach:
C++
// C++ implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right
// are palindromic paths
#include <bits/stdc++.h>
using namespace std;
#define M 3
#define N 3
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
int minchanges(int mat[N][M])
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
unordered_map<int, int> mp;
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
mp[(mat[i][j])]++;
totalsize++;
}
else if (i + j == right) {
mp[(mat[i][j])]++;
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
unordered_map<int, int>::iterator itr = mp.begin();
int changes = 0;
for (; itr != mp.end(); itr++)
changes = max(changes, itr->second);
// Minimum no. of changes will
// be the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Drive Code
int main()
{
int mat[][M]
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
cout << minchanges(mat);
return 0;
}
Java
// Java implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right are palindromic
// paths
import java.io.*;
import java.util.*;
class GFG {
static final int M = 3;
static final int N = 3;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
static int minchanges(int[][] mat)
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
Map<Integer, Integer> mp = new HashMap<>();
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
mp.put(mat[i][j],
mp.getOrDefault(mat[i][j], 0)
+ 1);
totalsize++;
}
else if (i + j == right) {
mp.put(mat[i][j],
mp.getOrDefault(mat[i][j], 0)
+ 1);
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
int changes = 0;
for (Map.Entry<Integer, Integer> itr :
mp.entrySet())
changes = Math.max(changes, itr.getValue());
// Minimum no. of changes will
// be the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Driver Code
public static void main(String[] args)
{
int mat[][]
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
System.out.println(minchanges(mat));
}
}
// This code is contributed by offbeat
Python3
# Python3 implementation to find the
# minimum number of changes required
# such that every path from top left
# to the bottom right
# are palindromic paths
M = 3
N = 3
# Function to find the minimum number
# of the changes required for the
# every path to be palindromic
def minchanges(mat):
# count variable for
# maintaining total changes.
count = 0
# left and right variables for
# keeping distance values
# from cell(0, 0) and
# (N-1, M-1) respectively.
left = 0
right = N + M - 2
while (left < right):
mp = {}
totalsize = 0
# Iterating over the matrix
for i in range(N):
for j in range(M):
if (i + j == left):
mp[(mat[i][j])] =
mp.get(mat[i][j], 0) + 1
totalsize += 1
elif (i + j == right):
mp[(mat[i][j])] =
mp.get(mat[i][j], 0) + 1
totalsize += 1
# Finding minimum number
# of changes required.
changes = 0
for itr in mp:
changes = max(changes, mp[itr])
# Minimum no. of changes will
# be the minimum no.
# of different values and
# we will assume to
# make them equals to value
# with maximum frequency element
count += totalsize - changes
# Moving ahead with
# greater distance
left += 1
right -= 1
return count
# Driver Code
if __name__ == '__main__':
mat = [[1, 4, 1],
[2, 5, 3],
[1, 3, 1]]
# Function Call
print(minchanges(mat))
# This code is contributed by Mohit Kumar 29
C#
// C# implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right are palindromic
// paths
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
static int M = 3;
static int N = 3;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
static int minchanges(int[, ] mat)
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
Dictionary<int, int> mp
= new Dictionary<int, int>();
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
if (mp.ContainsKey(mat[i, j])) {
mp[(mat[i, j])]++;
}
else {
mp[(mat[i, j])] = 1;
}
totalsize++;
}
else if (i + j == right) {
if (mp.ContainsKey(mat[i, j])) {
mp[(mat[i, j])]++;
}
else {
mp[(mat[i, j])] = 1;
}
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
int changes = 0;
foreach(KeyValuePair<int, int> itr in mp)
{
changes = Math.Max(changes, itr.Value);
}
// Minimum no. of changes will
// be the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Driver Code
public static void Main(string[] args)
{
int[, ] mat
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
Console.Write(minchanges(mat));
}
}
// This code is contributed by rutvik_56
JavaScript
<script>
// Javascript implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right
// are palindromic paths
var M = 3
var N = 3;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
function minchanges(mat)
{
// count variable for
// maintaining total changes.
var count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
var left = 0, right = N + M - 2;
while (left < right) {
var mp = new Map();
var totalsize = 0;
// Iterating over the matrix
for (var i = 0; i < N; i++) {
for (var j = 0; j < M; j++) {
if (i + j == left || i + j == right) {
if(mp.has(mat[i][j]))
mp.set(mat[i][j], mp.get(mat[i][j])+1)
else
mp.set(mat[i][j], 1)
totalsize++;
}
}
}
var changes = 0;
// Finding minimum number
// of changes required.
mp.forEach((value, key) => {
changes = Math.max(changes, value);
});
// Minimum no. of changes will
// be the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Drive Code
var mat
= [ [ 1, 4, 1 ], [ 2, 5, 3 ], [ 1, 3, 1 ] ];
// Function Call
document.write( minchanges(mat));
// This code is contributed by importantly.
</script>
Performance Analysis:
- Time Complexity: O(N3)
- Auxiliary Space: O(N)
Efficient Approach:
Algorithm:
- We will use a hashmap to count the frequency of every element which are the same distance from the top and bottom.
- We will use a 2D map for this where the key will be index and the value will be another map which will count frequency
- After counting frequency we will iterate l=0 to r=m+n-1 while l<r and each time we will count the sum and find the max frequency value ?f
- We will replace (sum-f) elements with the element whose frequency is maximum and store result+=(sum-f)
- Print result
Below is the implementation of the above approach:
C++
// C++ Program to count minimum change
// required to convert all the paths
// pallindromic from top left to
// right bottom cell.
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
int minchanges(vector<vector<int> >& a)
{
int res = 0; // use to store final result
// Row and column
int N = a.size(), M = a[0].size();
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D map
map<int, map<int, int> > mp;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// calculating position
int ind = i + j;
// increase the frequency of a[i][j]
// at position ind
mp[ind][a[i][j]]++;
}
}
// Define left and right limit
int r = M + N - 2, l = 0;
while (l < r) {
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
int s = 0, mx = 0;
// store all elements frequency at index l
for (auto x : mp[r]) {
mp[l][x.first] += x.second;
}
// Count total elements and mx->max_frequency
for (auto x : mp[l]) {
s += x.second;
mx = max(x.second, mx);
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
int main()
{
// Function Call
vector<vector<int> > mat
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
cout << "Total number of changes requires "
<< minchanges(mat) << "\n";
// Function Call
vector<vector<int> > mat1
= { { 1, 4 }, { 2, 5 }, { 1, 3 }, { 2, 5 } };
cout << "Total number of changes requires "
<< minchanges(mat1) << "\n";
return 0;
}
// This code is contributed by ajaykr00kj
Java
import java.util.*;
class Main {
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
public static int minchanges(int[][] a) {
int res = 0; // use to store final result
// Row and column
int N = a.length;
int M = a[0].length;
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D dictionary
Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// calculating position
int ind = i + j;
// increase the frequency of a[i][j]
// at position ind
if (!mp.containsKey(ind)) {
mp.put(ind, new HashMap<>());
}
mp.get(ind).put(a[i][j], mp.get(ind).getOrDefault(a[i][j], 0) + 1);
}
}
// Define left and right limit
int r = M + N - 2;
int l = 0;
while (l < r) {
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
int s = 0;
int mx = 0;
// store all elements frequency at index l
for (int x : mp.get(r).keySet()) {
if (!mp.containsKey(l)) {
mp.put(l, new HashMap<>());
}
mp.get(l).put(x, mp.get(l).getOrDefault(x, 0) + mp.get(r).get(x));
}
// Count total elements and mx->max_frequency
for (int x : mp.get(l).keySet()) {
s += mp.get(l).get(x);
mx = Math.max(mp.get(l).get(x), mx);
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
public static void main(String[] args) {
// Function Call
int[][] mat = {{1, 4, 1}, {2, 5, 3}, {1, 3, 1}};
System.out.println("Total number of changes required: " + minchanges(mat));
// Function Call
int[][] mat1 = {{1, 4}, {2, 5}, {1, 3}, {2, 5}};
System.out.println("Total number of changes required: " + minchanges(mat1));
}
}
Python3
# Python program to count minimum change
# required to convert all the paths
# pallindromic from top left to
# right bottom cell.
# Function to find the minimum number
# of the changes required for the
# every path to be palindromic
def minchanges(a):
res = 0 # use to store final result
# Row and column
N = len(a)
M = len(a[0])
# mp_key -> (i+j) , mp_value -> nw_map
# nw_map_key -> elements_of_matrix
# nw_map_value -> frequency of elements
# 2-D dictionary
mp = {}
for i in range(N):
for j in range(M):
# calculating position
ind = i + j
# increase the frequency of a[i][j]
# at position ind
if ind not in mp:
mp[ind] = {}
mp[ind][a[i][j]] = mp[ind].get(a[i][j], 0) + 1
# Define left and right limit
r = M + N - 2
l = 0
while l < r:
# s-> count total number of elements
# at index l and r
# mx-> store maximum frequency of any element
s = 0
mx = 0
# store all elements frequency at index l
for x in mp[r]:
if l not in mp:
mp[l] = {}
mp[l][x] = mp[l].get(x, 0) + mp[r][x]
# Count total elements and mx->max_frequency
for x in mp[l]:
s += mp[l][x]
mx = max(mp[l][x], mx)
# We will replace (s-mx) elements with
# the element whose frequency is mx
res += (s - mx)
l += 1
r -= 1
# return res
return res
# Driver Code
if __name__ == '__main__':
# Function Call
mat = [[1, 4, 1], [2, 5, 3], [1, 3, 1]]
print("Total number of changes required: ",
minchanges(mat))
# Function Call
mat1 = [[1, 4], [2, 5], [1, 3], [2, 5]]
print("Total number of changes required: ",
minchanges(mat1))
C#
using System;
using System.Collections.Generic;
class Program
{
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
static int MinChanges(List<List<int>> a)
{
int res = 0; // use to store final result
// Row and column
int N = a.Count, M = a[0].Count;
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D dictionary
Dictionary<int, Dictionary<int, int>> mp = new Dictionary<int,
Dictionary<int, int>>();
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
// calculating position
int ind = i + j;
// increase the frequency of a[i][j]
// at position ind
if (!mp.ContainsKey(ind))
mp[ind] = new Dictionary<int, int>();
if (!mp[ind].ContainsKey(a[i][j]))
mp[ind][a[i][j]] = 0;
mp[ind][a[i][j]]++;
}
}
// Define left and right limit
int r = M + N - 2, l = 0;
while (l < r)
{
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
int s = 0, mx = 0;
// store all elements frequency at index l
if (!mp.ContainsKey(r))
mp[r] = new Dictionary<int, int>();
foreach (var x in mp[r])
{
if (!mp.ContainsKey(l))
mp[l] = new Dictionary<int, int>();
if (!mp[l].ContainsKey(x.Key))
mp[l][x.Key] = 0;
mp[l][x.Key] += x.Value;
}
// Count total elements and mx->max_frequency
foreach (var x in mp[l])
{
s += x.Value;
mx = Math.Max(x.Value, mx);
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
static void Main(string[] args)
{
// Function Call
List<List<int>> mat = new List<List<int>>()
{
new List<int>() { 1, 4, 1 },
new List<int>() { 2, 5, 3 },
new List<int>() { 1, 3, 1 }
};
Console.WriteLine("Total number of changes required: " + MinChanges(mat));
// Function Call
List<List<int>> mat1 = new List<List<int>>()
{
new List<int>() { 1, 4 },
new List<int>() { 2, 5 },
new List<int>() { 1, 3 },
new List<int>() { 2, 5 }
};
Console.WriteLine("Total number of changes required: " + MinChanges(mat1));
}
}
JavaScript
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
function minchanges(a) {
let res = 0; // use to store final result
// Row and column
let N = a.length, M = a[0].length;
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D map
let mp = new Map();
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
// calculating position
let ind = i + j;
// increase the frequency of a[i][j]
// at position ind
if(mp.has(ind)){
let nw_map = mp.get(ind);
if(nw_map.has(a[i][j]))
nw_map.set(a[i][j], nw_map.get(a[i][j])+1);
else
nw_map.set(a[i][j], 1);
mp.set(ind, nw_map);
}else{
let nw_map = new Map();
nw_map.set(a[i][j], 1);
mp.set(ind, nw_map);
}
}
}
// Define left and right limit
let r = M + N - 2, l = 0;
while (l < r) {
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
let s = 0, mx = 0;
// store all elements frequency at index l
if(mp.has(r)){
let nw_map_r = mp.get(r);
for (const [key, value] of nw_map_r.entries()) {
if(mp.has(l)){
let nw_map_l = mp.get(l);
if(nw_map_l.has(key))
nw_map_l.set(key, nw_map_l.get(key)+value);
else
nw_map_l.set(key, value);
mp.set(l, nw_map_l);
}else{
let nw_map_l = new Map();
nw_map_l.set(key, value);
mp.set(l, nw_map_l);
}
}
}
// Count total elements and mx->max_frequency
if(mp.has(l)){
let nw_map_l = mp.get(l);
for (const [key, value] of nw_map_l.entries()) {
s += value;
mx = Math.max(value, mx);
}
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
// Function Call
let mat = [ [ 1, 4, 1 ], [ 2, 5, 3 ], [ 1, 3, 1 ] ];
console.log(`Total number of changes requires: ${minchanges(mat)}`);
// Function Call
let mat1 = [ [ 1, 4 ], [ 2, 5 ], [ 1, 3 ], [ 2, 5 ] ];
console.log(`Total number of changes requires: ${minchanges(mat1)}`);
OutputTotal number of changes requires 2
Total number of changes requires 3
Time Complexity: O(m*n)
Space Complexity: O(m*n)
Similar Reads
Minimum steps to convert all paths in matrix from top left to bottom right as palindromic paths | Set 2
Given a matrix mat[][] with N rows and M columns. The task is to find the minimum number of changes required in the matrix such that every path from top left to bottom right is a palindromic path. In a path only right and bottom movements are allowed from one cell to another cell. Examples: Input: M
12 min read
Minimum steps to convert all top left to bottom right paths in Matrix as palindrome | Set 2
Given a matrix mat[][] with N rows and M columns. The task is to find the minimum number of changes required in the matrix such that every path from top left to bottom right is a palindromic path. In a path only right and bottom movements are allowed from one cell to another cell. Examples: Input: m
9 min read
Print all palindromic paths from top left to bottom right in a matrix
Given a m*n matrix mat[][] containing only lowercase alphabetical characters, the task is to print all palindromic paths from the top-left cell to the bottom-right cell. A path is defined as a sequence of cells starting from the top-left and ending at the bottom-right, and we can only move right or
7 min read
Minimum cost to reach from the top-left to the bottom-right corner of a matrix
Given an N * M matrix mat[][] consisting of lower case characters, the task is to find the minimum cost to reach from the cell mat[0][0] to the cell mat[N-1][M-1]. If you are at a cell mat[i][j], you can jump to the cells mat[i+1][j], mat[i][j+1], mat[i-1][j], mat[i][j-1] (without going out of bound
11 min read
Maximum path sum from top left to bottom right of a matrix passing through one of the given cells
Given a matrix mat[][] of dimensions N * M and a set of coordinates of cell coordinates[][] of size Q, the task is to find the maximum sum of a path from the top-left cell (1, 1) to the bottom-right cell (N, M), such that the path should contain at least one of the coordinates from the array coordin
15 min read
Maximum XOR of a path from top-left to bottom-right cell of given Matrix
Given a matrix, mat[][] of dimensions N * M, the task is to print the maximum bitwise XOR value that can be obtained for a path from the top-left cell (0, 0) to the bottom-right cell (N - 1, M - 1) of the given matrix. Only possible moves from any cell (i, j) are (i + 1, j) and (i, j + 1). Note: Bit
9 min read
Maximum sum path in a matrix from top-left to bottom-right
Given a matrix mat[][] of dimensions N * M, the task is to find the path from the top-left cell (0, 0) to the bottom-right cell (N - 1, M - 1) of the given matrix such that sum of the elements in the path is maximum. The only moves allowed from any cell (i, j) of the matrix are (i + 1, j) or (i, j +
12 min read
Maximize cost to reach the bottom-most row from top-left and top-right corner of given matrix
Given a matrix grid[][] of size M * N where each cell of the matrix denotes the cost to be present on that cell. The task is to maximize the cost of moving to the bottom-most row from top-left and top-right corner of the matrix where in each step: From the cell (i, j) there can be a movement to (i+1
15+ min read
Minimize count of unique paths from top left to bottom right of a Matrix by placing K 1s
Given two integers N and M where M and N denote a matrix of dimensions N * M consisting of 0's only. The task is to minimize the count of unique paths from the top left (0, 0) to bottom right (N - 1, M - 1) of the matrix across cells consisting of 0's only by placing exactly K 1s in the matrix. Note
10 min read
Minimize maximum adjacent difference in a path from top-left to bottom-right
Given a matrix arr[][] of size M * N, where arr[i][j] represents the height of the cell (row, col). The task is to find a path from top-left to bottom-right such that the value of the maximum difference in height between adjacent cells is minimum for that path. Note: A path energy is the maximum abs
12 min read