具有相等行、列和对角线和的最大平方子矩阵
给定一个维度为N*M的矩阵mat[][] ,任务是找到最大方形子矩阵的大小,使得该子矩阵中所有行、列、对角线的总和相等。
例子:
Input: N = 3, M = 4, mat[][] = [[5, 1, 3, 1], [9, 3, 3, 1], [1, 3, 3, 8]]
Output: 2
Explanation:
The submatrix which satisfies all the given conditions is shown in bold
5 1 3 1
9 3 3 1
1 3 3 8
Therefore, 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: 3
Explanation:
The submatrix which satisfies all the given conditions is shown in bold
7 1 4 5 6
2 5 1 6 4
1 5 4 3 2
1 2 7 3 4
Therefore, the size of the submatrix is 3.
方法:给定的问题可以通过找到所有行和列的前缀和来解决,然后从矩阵的每个单元格迭代所有可能大小的方形子矩阵,如果存在任何满足给定标准的方形矩阵然后打印那个大小的方阵。请按照以下步骤解决问题:
- 维护两个前缀和数组prefixSumRow[]和prefixSumColumn[] ,分别存储给定矩阵的行和列的前缀和。
- 执行以下步骤以检查从大小为K的单元格(i, j)开始的任何方阵是否满足给定条件:
- 找到子矩阵 mat[i][j] 到mat[i + K][j + K]的主对角线元素的总和,并将其存储在变量中,比如sum 。
- 如果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)