
题解:动态规划,记录每个点左边连续的1的个数(包含自己)。dp[i][j] = cnt;
对每个点所在行以该点为矩形右下角的矩形数量就为dp[i][j]
比如上面的mat[2][1]对应的就为 [1]、[1,1]即sum = dp[2][1] = 2;
向上拓展 (每层能拓展的矩形为min(now,min(before))),意思就是dp[1][1] = 2那么能拓展的就是[1, 和[1,1
1] 1,1]。
可以理解为我们从底向上试探,找出可以拓展的矩形,而对当前拓展的每一层来看,它所有下面的层都是它的基石,能拓展出的矩形就为min(now,min(before))(矩形长度不能超过基石的最小值)。
代码:
class Solution {
public:
int numSubmat(vector<vector<int>>& mat) {
int row = mat.size();
int column = mat[0].size();
vector<vector<int> >dp(row,vector<int>(column));
for (int i = 0;i < row;i++) {
int cnt = 0;
for (int j = 0;j < column;j++) {
if (mat[i][j] == 1) {
cnt++;
}
else {
cnt = 0;
}
dp[i][j] = cnt;
}
}
int res = 0;
for (int i = 0;i < row;i++) {
for (int j = 0;j < column;j++) {
int sum = dp[i][j],m = dp[i][j];
if (sum > 0) {
for (int k = i - 1;k >= 0;k--) {
m = min(m,dp[k][j]);
sum += m;
}
res += sum;
}
}
}
return res;
}
};