leetcode 1292(二维前缀和)

1292: 元素和小于等于阈值的正方形的最大边长

思路1:一维前缀和+暴力枚举

复制代码
class Solution {
public:
    int maxSideLength(vector<vector<int>>& mat, int threshold) {
        int m=mat.size(),n=mat[0].size();
        vector<vector<int>> rowPrefix(m+1,vector<int>(n+1));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                rowPrefix[i+1][j+1]=rowPrefix[i+1][j]+mat[i][j];
            }
        }
        for(int k=min(m,n);k>0;k--){
            for(int r=0;r+k<=m;r++){
                for(int c=0;c+k<=n;c++){ //枚举正方形左上角(r,c)
                    long long sum=0;
                    for(int i=r;i<r+k;i++){
                        sum+=rowPrefix[i+1][c+k]-rowPrefix[i+1][c];
                        if(sum>threshold) break;
                    }
                    if(sum<=threshold){
                        return k;
                    }
                }
            }
        }
        return 0;
    }
};

思路2:二维前缀和

预处理二维前缀和后,暴力的做法是写一个三重循环:

  • 外面两重循环,枚举正方形的左上角 (i,j)。
  • 最内层循环,枚举正方形的边长为 1,2,3,... 直到出界或者正方形元素和超过 threshold 为止。在此过程中更新答案 ans 的最大值。

这样做的时间复杂度是 O(mn min(m,n))。

只需改一个地方,就能让算法的时间复杂度变小:

  • 最内层循环,从 ans+1 开始枚举。

比如现在 ans=3,那么枚举正方形的边长为 1,2,3 是毫无意义的,不会让答案变得更大。所以直接从 ans+1=4 开始枚举更好。

复制代码
class Solution {
public:
    int maxSideLength(vector<vector<int>>& mat, int threshold) {
        int m=mat.size(),n=mat[0].size();
        vector sum(m+1,vector<int>(n+1));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                sum[i+1][j+1]=sum[i+1][j]+sum[i][j+1]-sum[i][j]+mat[i][j];
            }
        }
        //返回左上角在(r1, c1),右下角在(r2, c2)的子矩阵元素和
        auto query=[&](int r1,int c1,int r2,int c2)->int{
            return sum[r2+1][c2+1]-sum[r2+1][c1]-sum[r1][c2+1]+sum[r1][c1];
        };

        int ans=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                //枚举边长为ans+1的正方形,左上角在(i, j),右下角在(i+ans, j+ans)
                while(i+ans<m && j+ans<n && query(i,j,i+ans,j+ans)<=threshold){
                    ans++; //确认ans+1可行后做ans++,即返回正确答案
                }
            }
        }

        return ans;
    }
};
相关推荐
江畔柳前堤8 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Doraemomo9 小时前
数据结构-环形链表
java·数据结构·链表
Forever Nore10 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考11 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX12 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面12 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号13 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽13 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI13 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
MC皮蛋侠客14 小时前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis