Largest square sub-matrix with equal row, column, and diagonal sum

06 Jun, 2022
Given a matrix mat[][] of dimensions N*M, the task is to find the size of the largest square submatrix such that the sum of all rows, columns, diagonals in that submatrix are equal.
Examples:
Input: N = 3, M = 4, mat[][] = [[5, 1, 3, 1], [9, 3, 3, 1], [1, 3, 3, 8]]Output: 2Explanation:The submatrix which satisfies all the given conditions is shown in bold5 1 3 19 3 3 11 3 3 8Therefore, the size of the submatrix is 2.
Input: N = 4, M = 5, mat[][] = [[7, 1, 4, 5, 6], [2, 5, 1, 6, 4], [1, 5, 4, 3, 2], [1, 2, 7, 3, 4]]Output: 3Explanation:The submatrix which satisfies all the given conditions is shown in bold7 1 4 5 62 5 1 6 41 5 4 3 21 2 7 3 4Therefore, the size of the submatrix is 3.
Approach: The given problem can be solved by finding the Prefix Sum of all the rows and the columns and then iterate for all possible sizes of the square submatrix from each cell of the matrix and if there exists any such square matrix that satisfies the given criteria then print that size of a square matrix. Follow the below steps to solve the problem:
Maintain two prefix sum arrays prefixSumRow[] and prefixSumColumn[] and store the prefix sum of rows and columns of the given matrix respectively.
Perform the following steps to check if any square matrix starting from the cell (i, j) of size K satisfy the given criteria or not:Find the sum of elements of primary diagonal of the submatrix mat[i][j] to mat[i + K][j + K] and store it in the variable, say sum.If the value of the sum is the same as the value mentioned below then return true. Otherwise, return false.The prefix sum of all the rows i.e., the value of prefixSumRow[k][j + K] – prefixSumRow[k][j] for all values of k over then range [i, i + K].The prefix sum of all the columns i.e., the value of prefixSumColumn[i + K][j] – prefixSumColumn[i][k] for all values of k over then range [j, j + K].The prefix sum of anti-diagonal elements.
Find the sum of elements of primary diagonal of the submatrix mat[i][j] to mat[i + K][j + K] and store it in the variable, say sum.If the value of the sum is the same as the value mentioned below then return true. Otherwise, return false.The prefix sum of all the rows i.e., the value of prefixSumRow[k][j + K] – prefixSumRow[k][j] for all values of k over then range [i, i + K].The prefix sum of all the columns i.e., the value of prefixSumColumn[i + K][j] – prefixSumColumn[i][k] for all values of k over then range [j, j + K].The prefix sum of anti-diagonal elements.
Find the sum of elements of primary diagonal of the submatrix mat[i][j] to mat[i + K][j + K] and store it in the variable, say sum.
If the value of the sum is the same as the value mentioned below then return true. Otherwise, return false.The prefix sum of all the rows i.e., the value of prefixSumRow[k][j + K] – prefixSumRow[k][j] for all values of k over then range [i, i + K].The prefix sum of all the columns i.e., the value of prefixSumColumn[i + K][j] – prefixSumColumn[i][k] for all values of k over then range [j, j + K].The prefix sum of anti-diagonal elements.
The prefix sum of all the rows i.e., the value of prefixSumRow[k][j + K] – prefixSumRow[k][j] for all values of k over then range [i, i + K].
The prefix sum of all the columns i.e., the value of prefixSumColumn[i + K][j] – prefixSumColumn[i][k] for all values of k over then range [j, j + K].
The prefix sum of anti-diagonal elements.
Now, iterate for all possible sizes of the square matrix that can be formed over the range [min(N, M), 1] and if there exist any possible satisfies the given criteria using the steps in the above steps, then print that size of a square matrix.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Define the prefix sum arrays globallyint prefix_sum_row[50][51];int prefix_sum_col[51][50]; bool is_valid(int r, int c, int size,              vector<vector<int> >& grid){    int r_end = r + size, c_end = c + size;     // Diagonal sum    int sum = 0;    for (int i = r, j = c; i < r_end; i++, j++) {        sum += grid[i][j];    }     // Check each row    for (int i = r; i < r_end; i++) {        if (prefix_sum_row[i][c_end]                - prefix_sum_row[i]            != sum) {            return false;        }    }     // Check each column    for (int i = c; i < c_end; i++) {        if (prefix_sum_col[r_end][i]                - prefix_sum_col[r][i]            != sum) {            return false;        }    }     // Check anti-diagonal    int ad_sum = 0;    for (int i = r, j = c_end - 1; i < r_end;         i++, j--) {        ad_sum += grid[i][j];    }     return ad_sum == sum;} int largestSquareValidMatrix(    vector<vector<int> >& grid){    // Store the size of the given grid    int m = grid.size(), n = grid[0].size();     // Compute the prefix sum for the rows    for (int i = 0; i < m; i++) {        for (int j = 1; j <= n; j++) {            prefix_sum_row[i][j]                = prefix_sum_row[i][j - 1]                  + grid[i][j - 1];        }    }     // Compute the prefix sum for the columns    for (int i = 1; i <= m; i++) {        for (int j = 0; j < n; j++) {            prefix_sum_col[i][j]                = prefix_sum_col[i - 1][j]                  + grid[i - 1][j];        }    }     // Check for all possible square submatrix    for (int size = min(m, n); size > 1; size--) {        for (int i = 0; i <= m - size; i++) {            for (int j = 0; j <= n - size; j++) {                if (is_valid(i, j, size, grid)) {                    return size;                }            }        }    }     return 1;} // Driver Codeint main(){    vector<vector<int> > grid = { { 7, 1, 4, 5, 6 },                                  { 2, 5, 1, 6, 4 },                                  { 1, 5, 4, 3, 2 },                                  { 1, 2, 7, 3, 4 } };    cout << largestSquareValidMatrix(grid);     return 0;}
// Java program for the above approachclass GFG{       // Define the prefix sum arrays globally    public static int[][] prefix_sum_row = new int[50][51];    public static int[][] prefix_sum_col = new int[51][50];     public static boolean is_valid(int r, int c, int size, int[][] grid) {        int r_end = r + size, c_end = c + size;         // Diagonal sum        int sum = 0;        for (int i = r, j = c; i < r_end; i++, j++) {            sum += grid[i][j];        }         // Check each row        for (int i = r; i < r_end; i++) {            if (prefix_sum_row[i][c_end] - prefix_sum_row[i] != sum) {                return false;            }        }         // Check each column        for (int i = c; i < c_end; i++) {            if (prefix_sum_col[r_end][i] - prefix_sum_col[r][i] != sum) {                return false;            }        }         // Check anti-diagonal        int ad_sum = 0;        for (int i = r, j = c_end - 1; i < r_end; i++, j--) {            ad_sum += grid[i][j];        }         return ad_sum == sum;    }     public static int largestSquareValidMatrix(int[][] grid) {        // Store the size of the given grid        int m = grid.length, n = grid[0].length;         // Compute the prefix sum for the rows        for (int i = 0; i < m; i++) {            for (int j = 1; j <= n; j++) {                prefix_sum_row[i][j] = prefix_sum_row[i][j - 1] + grid[i][j - 1];            }        }         // Compute the prefix sum for the columns        for (int i = 1; i <= m; i++) {            for (int j = 0; j < n; j++) {                prefix_sum_col[i][j] = prefix_sum_col[i - 1][j] + grid[i - 1][j];            }        }         // Check for all possible square submatrix        for (int size = Math.min(m, n); size > 1; size--) {            for (int i = 0; i <= m - size; i++) {                for (int j = 0; j <= n - size; j++) {                    if (is_valid(i, j, size, grid)) {                        return size;                    }                }            }        }         return 1;    }     // Driver Code    public static void main(String args[]) {        int[][] grid = { { 7, 1, 4, 5, 6 }, { 2, 5, 1, 6, 4 }, { 1, 5, 4, 3, 2 }, { 1, 2, 7, 3, 4 } };        System.out.println(largestSquareValidMatrix(grid));     } } // This code is contributed by saurabh_jaiswal.
## Python program for the above approach: ## Define the prefix sum arrays globallyprefix_sum_row = [[0]*51 for _ in range(50)]prefix_sum_col = [[0]*50 for _ in range(51)] def is_valid(r, c, size, grid):         r_end = r + size    c_end = c + size     ## Diagonal sum    sum = 0;    j = c    for i in range(r, r_end):        sum += grid[i][j];        j+=1     ## Check each row    for i in range(r, r_end):        if ((prefix_sum_row[i][c_end] - prefix_sum_row[i]) != sum):            return False     ## Check each column    for i in range(c, c_end):        if ((prefix_sum_col[r_end][i] - prefix_sum_col[r][i]) != sum):            return False     ## Check anti-diagonal    ad_sum = 0;    j = c_end - 1    for i in range(r, r_end):        ad_sum += grid[i][j]        j-=1     return (ad_sum == sum) def largestSquareValidMatrix(grid):     ## Store the size of the given grid    m = len(grid)    n = len(grid[0])     ## Compute the prefix sum for the rows    for i in range(0, m):        for j in range(1, n+1):            prefix_sum_row[i][j] = prefix_sum_row[i][j - 1] + grid[i][j - 1];         ## Compute the prefix sum for the columns    for i in range(1, m+1):        for j in range(0, n):            prefix_sum_col[i][j] = prefix_sum_col[i - 1][j] + grid[i - 1][j]      ## Check for all possible square submatrix    for size in range(min(m, n), 1, -1):        for i in range(0, m-size+1):            for j in range(0, n-size+1):                if (is_valid(i, j, size, grid)):                    return size     return 1 ## Driver codeif __name__=='__main__':     grid =  [   [ 7, 1, 4, 5, 6 ],                [ 2, 5, 1, 6, 4 ],                [ 1, 5, 4, 3, 2 ],                [ 1, 2, 7, 3, 4 ]            ]                 print(largestSquareValidMatrix(grid))     # This code is contributed by subhamgoyal2014.
// C# program for the above approachusing System;class GFG{       // Define the prefix sum arrays globally    public static int[,] prefix_sum_row = new int[50,51];    public static int[,] prefix_sum_col = new int[51,50];     public static bool is_valid(int r, int c, int size, int[,] grid) {        int r_end = r + size, c_end = c + size;         // Diagonal sum        int sum = 0;        for (int i = r, j = c; i < r_end; i++, j++) {            sum += grid[i,j];        }         // Check each row        for (int i = r; i < r_end; i++) {            if (prefix_sum_row[i,c_end] - prefix_sum_row[i,c] != sum) {                return false;            }        }         // Check each column        for (int i = c; i < c_end; i++) {            if (prefix_sum_col[r_end,i] - prefix_sum_col[r,i] != sum) {                return false;            }        }         // Check anti-diagonal        int ad_sum = 0;        for (int i = r, j = c_end - 1; i < r_end; i++, j--) {            ad_sum += grid[i,j];        }         return ad_sum == sum;    }     public static int largestSquareValidMatrix(int[,] grid) {        // Store the size of the given grid        int m = grid.GetLength(0), n = grid.GetLength(1);         // Compute the prefix sum for the rows        for (int i = 0; i < m; i++) {            for (int j = 1; j <= n; j++) {                prefix_sum_row[i,j] = prefix_sum_row[i,j - 1] + grid[i,j - 1];            }        }         // Compute the prefix sum for the columns        for (int i = 1; i <= m; i++) {            for (int j = 0; j < n; j++) {                prefix_sum_col[i,j] = prefix_sum_col[i - 1,j] + grid[i - 1,j];            }        }         // Check for all possible square submatrix        for (int size = Math.Min(m, n); size > 1; size--) {            for (int i = 0; i <= m - size; i++) {                for (int j = 0; j <= n - size; j++) {                    if (is_valid(i, j, size, grid)) {                        return size;                    }                }            }        }         return 1;    }     // Driver Code    public static void Main() {        int[,] grid = { { 7, 1, 4, 5, 6 }, { 2, 5, 1, 6, 4 },                       { 1, 5, 4, 3, 2 }, { 1, 2, 7, 3, 4 } };        Console.WriteLine(largestSquareValidMatrix(grid));     } } // This code is contributed by ukasp.
<script>       // JavaScript Program to implement       // the above approach        // Define the prefix sum arrays globally       let prefix_sum_row = new Array(50);       for (let i = 0; i < prefix_sum_row.length; i++) {           prefix_sum_row[i] = new Array(51).fill(0);       }       let prefix_sum_col = new Array(50);       for (let i = 0; i < prefix_sum_col.length; i++) {           prefix_sum_col[i] = new Array(51).fill(0);       }       function is_valid(r, c, size, grid) {           let r_end = r + size, c_end = c + size;            // Diagonal sum           let sum = 0;           for (let i = r, j = c; i < r_end; i++, j++) {               sum += grid[i][j];           }           // Check each row           for (let i = r; i < r_end; i++) {               if (prefix_sum_row[i][c_end]                   - prefix_sum_row[i]                   != sum) {                   return false;               }           }            // Check each column           for (let i = c; i < c_end; i++) {               if (prefix_sum_col[r_end][i]                   - prefix_sum_col[r][i]                   != sum) {                   return false;               }           }            // Check anti-diagonal           let ad_sum = 0;           for (let i = r, j = c_end - 1; i < r_end;               i++, j--) {               ad_sum += grid[i][j];           }            return ad_sum == sum;       }        function largestSquareValidMatrix(grid) {           // Store the size of the given grid           let m = grid.length, n = grid[0].length;            // Compute the prefix sum for the rows           for (let i = 0; i < m; i++) {               for (let j = 1; j <= n; j++) {                   prefix_sum_row[i][j]                       = prefix_sum_row[i][j - 1]                       + grid[i][j - 1];               }           }            // Compute the prefix sum for the columns           for (let i = 1; i <= m; i++) {               for (let j = 0; j < n; j++) {                   prefix_sum_col[i][j]                       = prefix_sum_col[i - 1][j]                       + grid[i - 1][j];               }           }            // Check for all possible square submatrix           for (let size = Math.min(m, n); size > 1; size--) {               for (let i = 0; i <= m - size; i++) {                   for (let j = 0; j <= n - size; j++) {                       if (is_valid(i, j, size, grid)) {                           return size;                       }                   }               }           }            return 1;       }        // Driver Code        let grid = [[7, 1, 4, 5, 6],       [2, 5, 1, 6, 4],       [1, 5, 4, 3, 2],       [1, 2, 7, 3, 4]];       document.write(largestSquareValidMatrix(grid));     // This code is contributed by Potta Lokesh    </script>
3
 
Time Complexity: O(N*M*min(N, M)2)Auxiliary Space: O(N*M)
lokeshpotta20
_saurabh_jaiswal
ukasp
subhamgoyal2014
prefix-sum
submatrix
Dynamic Programming
Greedy
Mathematical
Matrix
prefix-sum
Dynamic Programming
Greedy
Mathematical
Matrix
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.