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 = 2, N = 2, mat[M][N] = {{0, 0}, {0, 1}} 
Output:
Explanation: 
Change matrix[0][0] from 0 to 1. The two paths from (0, 0) to (1, 1) become palindromic.

Input: M = 3, N = 7, mat[M][N] = {{1, 2, 3, 4, 5, 6, 7}, {2, 2, 3, 3, 4, 3, 2}, {1, 2, 3, 2, 5, 6, 4}} 
Output: 10

Naive Approach: For the Naive Approach please refer to this article. 

Time Complexity: O(N^3) 
Auxiliary Space: O(N)

Efficient Approach: 
The following observations have to be made: 



  • A unique diagonal exists for every value (i+j) where i is the row index and j is the column index.
  • The task reduces to selecting two diagonals, which are at the same distance from cell (0, 0) and cell (M – 1, N – 1) respectively and making all their elements equal to a single number, which is repeated most number of times in both the chosen diagonals.
  • If the number of elements between cell (0, 0) and (M – 1, N – 1) are odd, then a common diagonal equidistant from both the cells exists. Elements of that diagonal need not be modified as they do not affect the palindromic arrangement of a path.
  • If the numbers of cells between (0, 0) and (M – 1, N – 1) are even, no such common diagonal exists.

Follow the below steps to solve the problem: 

  1. Create a 2D array frequency_diagonal that stores the frequency of all numbers in each chosen diagonal.
  2. Each diagonal can be uniquely represented as the sum of (i, j).
  3. Initialise a count variable that stores the count of the total number of cells where the values have to be replaced.
  4. Iterate over the mat[][] and increment the frequency of current element in the diagonal ((i + j) value) where it belongs to.
  5. Initialize a variable number_of_elements to 1, which stores the number of elements in each of the currently chosen pair of diagonals.
  6. Initialize start = 0 and end = M + N – 2 and repeat the steps below until start < end
    • Find the frequency of the number which appears maximum times in the two selected diagonals that are equidistant from (0, 0) and (M-1, N-1).
    • Let the frequency in the above step be X. Add the value (total number of elements in the two diagonals – X) to count the minimum number of changes.
    • Increment start by 1 and decrement end by 1 and if the number of elements in the current diagonal is less than the maximum possible elements in any diagonal of the matrix, then increment number_of_elements by 1.
  7. Print the value of total count after the above steps.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program of the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate the minimum
// number of replacements
int MinReplacements(
    int M, int N, int mat[][30])
{
  
    // 2D array to store frequency
    // of all the numners in
    // each diaginal
  
    int frequency_diagonal[100][10005];
  
    // Initialise all the elements
    // of 2D array with 0
    memset(frequency_diagonal, 0,
           sizeof(frequency_diagonal));
  
    // Initialise answer as 0
    int answer = 0;
  
    // Iterate over the matrix
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
  
            // Update the frequency of
            // number mat[i][j]
            // for the diagonal
            // identified by (i+j)
            frequency_diagonal[i + j]
                              [mat[i][j]]++;
        }
    }
  
    // Initialize start as 0
    // which indicates the
    // first diagonal
    int start = 0;
  
    // Initialize end as
    // M + N - 2 which indicates
    // the last diagonal
    int end = M + N - 2;
  
    // Number of elements in
    // the current diagonal
    int no_of_elemnts = 1;
  
    // Maximum possible number
    // of elements in a diagonal
    // can be minimum of (number of
    // rows and number of columns)
    int max_elements = min(M, N);
  
    while (start < end) {
  
        // The frequecny of number
        // which occurs for the
        // maximum number of times
        // in the two selected
        // diagonals
        int X = INT_MIN;
  
        for (int i = 0; i <= 10000; i++) {
            X = max(
                X,
                frequency_diagonal[start][i]
                    + frequency_diagonal[end][i]);
        }
  
        answer = answer + (2 * (no_of_elemnts)) - X;
  
        // Increment start
        start++;
        // Decrement end
        end--;
  
        // Increment current number
        // of elements until it reaches
        // the maximum possible value
        if (no_of_elemnts < max_elements)
            no_of_elemnts++;
    }
  
    // return the final answer
    return answer;
}
  
// Driver Code
int main()
{
    // Number of rows
    int M = 3;
  
    // Number of columns
    int N = 7;
  
    int mat[30][30]
        = { { 1, 2, 3, 4, 5, 6, 7 },
            { 2, 2, 3, 3, 4, 3, 2 },
            { 1, 2, 3, 2, 5, 6, 4 } };
  
    cout << MinReplacements(M, N, mat)
         << endl;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program of the above approach
class GFG{
  
// Function to calculate the minimum
// number of replacements
static int MinReplacements(int M, int N,
                           int mat[][])
{
      
    // 2D array to store frequency
    // of all the numners in
    // each diaginal
    int [][]frequency_diagonal = new int[100][10005];
  
    // Initialise answer as 0
    int answer = 0;
  
    // Iterate over the matrix
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++) 
        {
  
            // Update the frequency of
            // number mat[i][j]
            // for the diagonal
            // identified by (i+j)
            frequency_diagonal[i + j][mat[i][j]]++;
        }
    }
  
    // Initialize start as 0
    // which indicates the
    // first diagonal
    int start = 0;
  
    // Initialize end as
    // M + N - 2 which indicates
    // the last diagonal
    int end = M + N - 2;
  
    // Number of elements in
    // the current diagonal
    int no_of_elemnts = 1;
  
    // Maximum possible number
    // of elements in a diagonal
    // can be minimum of (number of
    // rows and number of columns)
    int max_elements = Math.min(M, N);
  
    while (start < end)
    {
  
        // The frequecny of number
        // which occurs for the
        // maximum number of times
        // in the two selected
        // diagonals
        int X = Integer.MIN_VALUE;
  
        for(int i = 0; i <= 10000; i++)
        {
            X = Math.max(X,
                frequency_diagonal[start][i] +
                frequency_diagonal[end][i]);
        }
  
        answer = answer + (2 * (no_of_elemnts)) - X;
  
        // Increment start
        start++;
          
        // Decrement end
        end--;
  
        // Increment current number
        // of elements until it reaches
        // the maximum possible value
        if (no_of_elemnts < max_elements)
            no_of_elemnts++;
    }
  
    // return the final answer
    return answer;
}
  
// Driver Code
public static void main(String[] args)
{
      
    // Number of rows
    int M = 3;
  
    // Number of columns
    int N = 7;
  
    int mat[][] = { { 1, 2, 3, 4, 5, 6, 7 },
                    { 2, 2, 3, 3, 4, 3, 2 },
                    { 1, 2, 3, 2, 5, 6, 4 } };
  
    System.out.print(MinReplacements(M, N, mat) + "\n");
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program of the above approach
import sys
  
# Function to calculate the minimum
# number of replacements
def MinReplacements(M, N, mat):
  
    # 2D array to store frequency
    # of all the numners in
    # each diaginal
    frequency_diagonal = [[0 for x in range(10005)]
                             for y in range (100)];
  
    # Initialise answer as 0
    answer = 0
  
    # Iterate over the matrix
    for i in range(M):
        for j in range(N):
  
            # Update the frequency of
            # number mat[i][j]
            # for the diagonal
            # identified by (i+j)
            frequency_diagonal[i + j][mat[i][j]] += 1
  
    # Initialize start as 0
    # which indicates the
    # first diagonal
    start = 0
  
    # Initialize end as
    # M + N - 2 which indicates
    # the last diagonal
    end = M + N - 2
  
    # Number of elements in
    # the current diagonal
    no_of_elemnts = 1
  
    # Maximum possible number
    # of elements in a diagonal
    # can be minimum of (number of
    # rows and number of columns)
    max_elements = min(M, N)
  
    while (start < end):
  
        # The frequecny of number
        # which occurs for the
        # maximum number of times
        # in the two selected
        # diagonals
        X = -sys.maxsize - 1
  
        for i in range(10001):
            X = max(X,
                    frequency_diagonal[start][i] +
                    frequency_diagonal[end][i])
          
        answer = answer + (2 * (no_of_elemnts)) - X
  
        # Increment start
        start += 1
          
        # Decrement end
        end -= 1
  
        # Increment current number
        # of elements until it reaches
        # the maximum possible value
        if (no_of_elemnts < max_elements):
            no_of_elemnts += 1
  
    # Return the final answer
    return answer
  
# Driver Code
  
# Number of rows
M = 3
  
# Number of columns
N = 7
  
mat = [ [ 1, 2, 3, 4, 5, 6, 7 ],
        [ 2, 2, 3, 3, 4, 3, 2 ],
        [ 1, 2, 3, 2, 5, 6, 4 ] ]
  
print(MinReplacements(M, N, mat))
  
# This code is contributed by chitranayal

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program of the above approach
using System;
  
class GFG{
  
// Function to calculate the minimum
// number of replacements
static int MinReplacements(int M, int N,
                           int [,]mat)
{
      
    // 2D array to store frequency
    // of all the numners in
    // each diaginal
    int [,]frequency_diagonal = new int[100, 10005];
  
    // Initialise answer as 0
    int answer = 0;
  
    // Iterate over the matrix
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++) 
        {
  
            // Update the frequency of
            // number mat[i,j]
            // for the diagonal
            // identified by (i+j)
            frequency_diagonal[i + j, mat[i, j]]++;
        }
    }
  
    // Initialize start as 0
    // which indicates the
    // first diagonal
    int start = 0;
  
    // Initialize end as
    // M + N - 2 which indicates
    // the last diagonal
    int end = M + N - 2;
  
    // Number of elements in
    // the current diagonal
    int no_of_elemnts = 1;
  
    // Maximum possible number
    // of elements in a diagonal
    // can be minimum of (number of
    // rows and number of columns)
    int max_elements = Math.Min(M, N);
  
    while (start < end)
    {
  
        // The frequecny of number
        // which occurs for the
        // maximum number of times
        // in the two selected
        // diagonals
        int X = int.MinValue;
  
        for(int i = 0; i <= 10000; i++)
        {
            X = Math.Max(X,
                frequency_diagonal[start, i] +
                frequency_diagonal[end, i]);
        }
  
        answer = answer + (2 * (no_of_elemnts)) - X;
  
        // Increment start
        start++;
          
        // Decrement end
        end--;
  
        // Increment current number
        // of elements until it reaches
        // the maximum possible value
        if (no_of_elemnts < max_elements)
            no_of_elemnts++;
    }
  
    // Return the readonly answer
    return answer;
}
  
// Driver Code
public static void Main(String[] args)
{
      
    // Number of rows
    int M = 3;
  
    // Number of columns
    int N = 7;
  
    int [,]mat = { { 1, 2, 3, 4, 5, 6, 7 },
                   { 2, 2, 3, 3, 4, 3, 2 },
                   { 1, 2, 3, 2, 5, 6, 4 } };
  
    Console.Write(MinReplacements(M, N, mat) + "\n");
}
}
  
// This code is contributed by amal kumar choubey 

chevron_right


Output: 

10

Time Complexity: O(M * N) 
Auxiliary Space: O(M * N)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.