题目
思路与算法
- 题意很好理解,但是本题的动态规划不是常规思路的,你需要很好的理解题意并仔细分析状态与转移关系,才能定义正确的dp数组以及其dp转移关系。
- dp [ i ] [ j ]为每个点前面连续的1的个数。只算当前行。总体这不是一道简单的动态题,作为最后两天的一个思路拓展,力扣196周周赛第三题,智力题嗷,当时卡死在这,大致清楚应该用动态,但是没想清楚状态,这两天翻出来又看了好久才看懂,具体的不分析了,见代码。
代码实现
class Solution {
public int numSubmat(int[][] mat) {
int[][] dp = new int[mat.length][mat[0].length];
int sum = 0;
for(int i = 0; i < mat.length; i++){
dp[i][0] = mat[i][0];
}
for(int i = 0; i < mat.length; i++){
for(int j = 0; j < mat[0].length; j++){
if(mat[i][j] == 0){
dp[i][j] = 0;
continue;
}
int min_len = Integer.MAX_VALUE;
if(j != 0)
dp[i][j] = dp[i][j - 1] + 1;
for(int k = i; k >= 0; k--){
min_len = Math.min(min_len, dp[k][j]);
sum += min_len;
}
}
}
return sum;
}
}
复杂度分析
只遍历一遍整个数组,时间复杂度为O(N*M)