个人练习-Leetcode-1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold

题目链接:https://leetcode.cn/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/

题目大意:给出一个m*n矩阵mat[][],求最大的满足以下条件的正方形的边长:正方形内元素之和小于等于threshold

思路:开始以为是DP,后来发现是用前缀和做。二维的前缀和还是第一次写。对于一个矩阵,从左上角到某一个点(i, j)的和为

pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + mat[mi][mj]

此处的mi, mj是考虑到mat[][]坐标从0开始,pre[][]坐标从1开始做的对应的转换。

因此第一次遍历计算所有前缀和。随后对于c,从最大的可能min(m, n)开始再次遍历,计算可能的c*c大小的正方形内元素之和,与threshold对比。正方形元素和的计算如下

    int sumRect(int x1, int y1, int x2, int y2) {
        return pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1];
    }

找到一个符合的c即可返回。

完整代码

class Solution {
public:
    int pre[301][301];

    int sumRect(int x1, int y1, int x2, int y2) {
        return pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1];
    }

    int maxSideLength(vector<vector<int>>& mat, int threshold) {
        int m = mat.size(), n = mat[0].size();
        memset(pre, 0, sizeof(pre));
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                int mi = i-1, mj = j-1;
                pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + mat[mi][mj];
            }
        }

        int c = min(m, n);
        int ret = 0;
        while (c > 0) {
            for (int sx = 1; sx <= m; sx++) {
                for (int sy = 1; sy <= n; sy++) {
                    if (sx+c-1 <= m && sy+c-1 <= n) {
                        if (sumRect(sx, sy, sx+c-1, sy+c-1) <= threshold) {
                            ret = c;
                            return ret;
                        }
                    }
                }
            }
            c--;
        }

        return ret;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值