LeetCode 元素和小于等于阈值的正方形的最大边长(前缀和+dp)

LeetCode周赛题
在这里插入图片描述

算法分析
前缀和+动态规划 时间复杂度:O(m * n * max(m, n)), 空间复杂度:O(n * m)
1. 这个题实际上是之前做过的最大边长的升级版
2. 需要额外计算一下前缀和,然后先求出可能的最长边长的上界,然后边长不断减减,直到不超过阈值
3. 最后更新f[i][j]和res即可

/**
 *    @Author: Wilson79
 *    @Datetime: 2019年12月15日 星期日 11:41:10
 *    @Filename: 元素和小于等于阈值的正方形的最大边长.cpp
 */


class Solution {
public:
    int maxSideLength(vector<vector<int>>& mat, int threshold) {
        int sum[310][310];
        memset(sum, 0, sizeof sum);
        int f[310][310];
        memset(f, 0, sizeof f);
        
        if (!mat.size() || !mat[0].size()) return 0;
        int m = mat.size(), n = mat[0].size();
        
        // 预处理前缀和
        for (int i = 1; i <= m; i ++) {
            for(int j = 1;  j <= n; j ++) {
                sum[i][j] = mat[i - 1][j - 1] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
            }
        }
        
        int res = -1;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j ++) {
                int t = min(f[i - 1][j - 1], min(f[i][j - 1], f[i - 1][j])) + 1;
                // 利用前缀和求子矩阵的和
                while(t > 0 && (sum[i][j] - sum[i - t][j] - sum[i][j - t] + sum[i - t][j - t] > threshold)) t --;
                f[i][j] = t;
                res = max(f[i][j], res);
            }
        }
        
        return res;
    }
};
发布了182 篇原创文章 · 获赞 71 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/103547153