重点是每次加上i-last
,i是最右边的0
的位置,左边可选的位置为[last+1,last+2,...i]
共i-last
个
java
class Solution {
public long zeroFilledSubarray(int[] nums) {
long ans = 0;
int last = -1;
for (int i = 0; i < nums.length; i++) {
int x = nums[i];
if (x != 0) {
last = i; // 记录上一个非 0 元素的位置
} else {
ans += i - last;
}
}
return ans;
}
}
这题重点是枚举上下两个边界,确定了边界,就确定了边长。然后题目变成了,统计有多少长度为h的全h子数组
java
class Solution {
public int countSquares(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int ans = 0;
for (int top = 0; top < m; top++) { // 枚举上边界
int[] a = new int[n];
for (int bottom = top; bottom < m; bottom++) { // 枚举下边界
int h = bottom - top + 1; // 高
// 2348. 全 h 子数组的数目
int last = -1;
for (int j = 0; j < n; j++) {
a[j] += matrix[bottom][j]; // 把 bottom 这一行的值加到 a 中
if (a[j] != h) {
last = j; // 记录上一个非 h 元素的位置
} else if (j - last >= h) { // 右端点为 j 的长为 h 的子数组全是 h
ans++;
}
}
}
}
return ans;
}
}
提取出来, T 2348. 全 h 子数组的数目
java
int last = -1;
for (int j = 0; j < n; j++) {
a[j] += matrix[bottom][j]; // 把 bottom 这一行的值加到 a 中
if (a[j] != h) {
last = j; // 记录上一个非 h 元素的位置
} else if (j - last >= h) { // 右端点为 j 的长为 h 的子数组全是 h
ans++;
}
}
这个比上一题简单,确定了高度h以后,再加一个第一题就可以了
java
class Solution {
public int numSubmat(int[][] mat) {
int m = mat.length;
int n = mat[0].length;
int ans = 0;
for (int top = 0; top < m; top++) { // 枚举上边界
int[] a = new int[n];
for (int bottom = top; bottom < m; bottom++) { // 枚举下边界
int h = bottom - top + 1; // 高
// 2348. 全 h 子数组的数目
int last = -1;
for (int j = 0; j < n; j++) {
a[j] += mat[bottom][j]; // 把 bottom 这一行的值加到 a 中
if (a[j] != h) {
last = j; // 记录上一个非 h 元素的位置
} else {
ans += j - last;
}
}
}
}
return ans;
}
}