LeetCode 363 矩形区域不超过 K 的最大数值和
Posted ambition-hhn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 363 矩形区域不超过 K 的最大数值和相关的知识,希望对你有一定的参考价值。
给定一个矩阵,要求找出矩阵内部不大于k的最大矩阵和。如果枚举每个矩阵,并计算其和,必定会超时。我最开始想的是暴力+动态规划,用dp[i][j]表示以(0,0)为左上角,以(i,j)为右下角的矩阵的和,这样子省去了重复计算矩阵和的时间,虽然能通过,但是时间复杂度还是到了O(m2n2),不是很好,优点就是简单易懂。后来,看了题解中的一些方法进行改进,因为题目中提到了行数可能远大于列数,我们固定列数的左右边界,之后求在边界中每行的和,然后再求出符合要求的矩阵和,时间复杂度是在理想的情况下可达到O(m2n),速度也有很大地提升。
暴力+动态规划
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;
}
};
以上是关于LeetCode 363 矩形区域不超过 K 的最大数值和的主要内容,如果未能解决你的问题,请参考以下文章
2022-01-20: 矩形区域不超过 K 的最大数值和。 给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。 题目数据保证总会存在一