📌  相关文章
📜  具有相等行、列和对角线和的最大平方子矩阵

📅  最后修改于: 2022-05-13 01:56:04.623000             🧑  作者: Mango

具有相等行、列和对角线和的最大平方子矩阵

给定一个维度为N*M的矩阵mat[][] ,任务是找到最大方形子矩阵的大小,使得该子矩阵中所有行、列、对角线的总和相等。

例子:

方法:给定的问题可以通过找到所有行和列的前缀和来解决,然后从矩阵的每个单元格迭代所有可能大小的方形子矩阵,如果存在任何满足给定标准的方形矩阵然后打印那个大小的方阵。请按照以下步骤解决问题:

  • 维护两个前缀和数组prefixSumRow[]prefixSumColumn[] ,分别存储给定矩阵的行和列的前缀和。
  • 执行以下步骤以检查从大小为K的单元格(i, j)开始的任何方阵是否满足给定条件:
    1. 找到子矩阵 mat[i][j] 到mat[i + K][j + K]的主对角线元素的总和,并将其存储在变量中,比如sum
    2. 如果sum的值与下面提到的值相同,则返回true 。否则,返回false
      • 所有行的前缀总和,即prefixSumRow[k][j + K] – prefixSumRow[k][j]对于所有k值超过然后范围[i, i + K]的值。
      • 所有列的前缀总和,即prefixSumColumn[i + K][j] – prefixSumColumn[i][k]的值,用于所有k值在[j, j + K]范围内。
      • 反对角元素的前缀和。
  • 现在,迭代可以在[min(N, M), 1]范围内形成的所有可能大小的方阵,如果存在满足给定标准的任何可能,则使用上述步骤中的步骤,然后打印该大小的方阵。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Define the prefix sum arrays globally
int prefix_sum_row[50][51];
int prefix_sum_col[51][50];
 
bool is_valid(int r, int c, int size,
              vector >& 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 >& 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 Code
int main()
{
    vector > 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
// Java program for the above approach
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 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.


C#
// C# program for the above approach
using 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.


Javascript


输出:
3

时间复杂度: O(N*M*min(N, M) 2 )
辅助空间: O(N*M)