题目
给你一个 m x n 的二进制矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。
思路
问题性质:方案数
数据规模:10^2,考虑n的三次方
算法:动态规划
基本思路:建立row数组,建立每行的不连续前缀和
动态规划基于row数组
子问题定义为:以[i,j]作为右下角的子矩形的个数
所以结果需要返回所有状态的和
代码
class Solution {
public:
int numSubmat(vector<vector<int>>& mat) {
// 问题性质:方案数
// 数据规模:
// 算法:动态规划
// 基本思路:建立row数组,建立每行的不连续前缀和
// 动态规划基于row数组
// 子问题定义为:以[i,j]作为右下角的子矩形的个数
// 所以结果需要返回所有状态的和
int m=mat.size();
int n=mat[0].size();
vector<vector<int>> row(m,vector<int>(n,0));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(j==0)
row[i][j]=mat[i][j];
else if(mat[i][j]){
row[i][j]=row[i][j-1]+1; // 建立不连续前缀和
}else{
row[i][j]=0;
}
}
}
int ans=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
int col=row[i][j];
for(int k=i;k>=0&&col;k--){ // k倒叙保证连续,同时一旦col为零,立即停止累加
col=min(col,row[k][j]);
ans+=col;
}
}
}
return ans;
}
};