有一个n*m的二维整型数组矩阵matrix
,计算它的最大子矩阵和(允许子矩阵为空)。
样例:
它的最大子矩阵和为29,对应的子矩阵为图中蓝色线条圈出的矩阵。
提示:时间复杂度O(n^3),可以先尝试完成最大连续子段和问题。
流传很广的题了。
void initAccSum(vector<vector<int> >& mat,vector<vector<int> >& accSum);
int maxSeqSum(vector<vector<int> >& accSum,vector<vector<int> >& mat,int r1,int r2);
int maxRectSum(vector<vector<int> > &matrix) {
int m=matrix.size();
if (m==0)
return 0;
int n=matrix[0].size();
vector<vector<int> > accSum(m,vector<int>(n,0));
initAccSum(matrix,accSum);
int maxSum=0;
for(int r1=0;r1<m;r1++)
for(int r2=r1;r2<m;r2++)
maxSum=max(maxSum,maxSeqSum(accSum,matrix,r1,r2));
return maxSum;
}
void initAccSum(vector<vector<int> >& mat,vector<vector<int> >& accSum)
{
int m=mat.size(),n=mat[0].size();
for(int i=0;i<n;i++)
accSum[0][i]=mat[0][i];
for(int i=1;i<m;i++)
for(int j=0;j<n;j++)
accSum[i][j]+=accSum[i-1][j]+mat[i][j];
}
int maxSeqSum(vector<vector<int> >& accSum,vector<vector<int> >& mat,int r1,int r2)
{
if ( r1>r2 )
return 0;
vector<int> seq(accSum[r1].size(),0);
int maxSum=0;
int pre=0;
for(int i=0;i<accSum[r1].size();i++)
seq[i]=accSum[r2][i]-accSum[r1][i]+mat[r1][i];
for(int i=0;i<seq.size();i++)
{
pre=max(pre+seq[i],seq[i]);
maxSum=max(maxSum,pre);
}
return maxSum;
}