zoukankan      html  css  js  c++  java
  • LeetCode 363 矩形区域不超过 K 的最大数值和

    给定一个矩阵,要求找出矩阵内部不大于k的最大矩阵和。如果枚举每个矩阵,并计算其和,必定会超时。我最开始想的是暴力+动态规划,用dp[i][j]表示以(0,0)为左上角,以(i,j)为右下角的矩阵的和,这样子省去了重复计算矩阵和的时间,虽然能通过,但是时间复杂度还是到了O(m²n²),不是很好,优点就是简单易懂。后来,看了题解中的一些方法进行改进,因为题目中提到了行数可能远大于列数,我们固定列数的左右边界,之后求在边界中每行的和,然后再求出符合要求的矩阵和,时间复杂度是在理想的情况下可达到O(m²n),速度也有很大地提升。

    暴力+动态规划

    class Solution {
    public:
        int dp[2005][2005];
        int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
            int n=matrix.size(),m;
            if(n) m=matrix[0].size();
            if(n==0) return 0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+matrix[i-1][j-1];
            int ans=-0x3f3f3f3f,t;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    for(int r=0;r<=i;r++)
                        for(int c=0;c<=j;c++)
                        if(r!=i&&c!=j)
                        {
                            t=dp[i][j]-dp[i][c]-dp[r][j]+dp[r][c];
                            if(t>ans&&t<=k) ans=t;
                        }
                }
        return ans;
        }
    };
    

    滚动数组+子区间和(改进版)

    class Solution {
    public:
        int dpmax(int *sum,int n,int k)
        {
            int ans=-0x3f3f3f3f,now=0;
            for(int i=0;i<n;i++)
            {
                if(now>0) now+=sum[i];
                else now=sum[i];
                if(now>ans) ans=now;  
            }
            if(ans<=k) return ans;
            ans=-0x3f3f3f3f;
            for(int i=0;i<n;i++)
            {
                now=0;
                for(int j=i;j<n;j++)
                {
                    now+=sum[j];
                    if(now<=k&&now>ans) ans=now;
                    if(ans==k) return ans;
                }
            }
            return ans;
        }
        int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
            int n=matrix.size(),m;
            if(n) m=matrix[0].size();
            if(n==0) return 0;
            int *sum=new int[n+1];
            int ans=-0x3f3f3f3f;
            for(int i=0;i<m;i++)
                for(int j=i;j<m;j++)
                {
                    for(int x=0;x<n;x++) sum[x]=0;
                    for(int r=0;r<n;r++)
                        for(int c=i;c<=j;c++)
                            sum[r]+=matrix[r][c];
                    ans=max(ans,dpmax(sum,n,k));
                }
            
            return ans;
        }
    };
    
  • 相关阅读:
    Redis常见7种使用场景(PHP)
    阻塞式I/O实现简单TCP通信
    telnet客户端程序
    TCP简单回射程序
    getsockname和getpeername函数
    close函数
    TCP时间获取程序
    listen函数
    基本套接字编程
    readline.c
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12844992.html
Copyright © 2011-2022 走看看