跳到主要内容

1277.统计全为 1 的正方形子矩阵

· 阅读需 3 分钟

1、题干

给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。

 

示例 1:

输入:matrix =
[
  [0,1,1,1],
  [1,1,1,1],
  [0,1,1,1]
]
输出:15
解释:
边长为 1 的正方形有 10 个。
边长为 2 的正方形有 4 个。
边长为 3 的正方形有 1 个。
正方形的总数 = 10 + 4 + 1 = 15.

示例 2:

输入:matrix = 
[
[1,0,1],
[1,1,0],
[1,1,0]
]
输出:7
解释:
边长为 1 的正方形有 6 个。
边长为 2 的正方形有 1 个。
正方形的总数 = 6 + 1 = 7.

 

提示:

  • 1 <= arr.length <= 300
  • 1 <= arr[0].length <= 300
  • 0 <= arr[i][j] <= 1

Problem: 1277. 统计全为 1 的正方形子矩阵

2、方法1

前缀和+暴力枚举

3、Code

function countSquares(matrix: number[][]): number {
const preSum = matrix.map(m => m.map(() => 0));

for (let i = 0; i < matrix.length; i++) {
let sumRow = 0;
for (let j = 0; j < matrix[0].length; j++) {
sumRow += matrix[i][j];
preSum[i][j] = sumRow + (i ? preSum[i - 1][j] : 0);
}
}

let ans = 0;

for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
for (let k = 1; k <= j + 1; k++) {
const sr = i - k > -1 ? preSum[i - k][j] : 0;
const sc = preSum[i][j - k] || 0;
const src = i - k > -1 && j - k > -1 ? preSum[i - k][j - k] : 0;
const s = preSum[i][j] - sr - sc + src;
if (s !== k ** 2) break;
ans++;
}
}
}

return ans;
};

4、复杂度

  • 时间复杂度:O(n3)O(n^3)
  • 空间复杂度:O(n2)O(n^2)

5、执行结果

image.png

6、方法2

动态规划

7、Code

function countSquares(matrix: number[][]): number {
let ans = 0;

for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
if (i && j && matrix[i][j]) matrix[i][j] = Math.min(matrix[i][j - 1], matrix[i - 1][j], matrix[i - 1][j - 1]) + 1;
ans += matrix[i][j];
}
}

return ans;
};

8、复杂度

  • 时间复杂度:O(n2)O(n^2)
  • 空间复杂度:O(1)O(1)

9、执行结果

image.png