给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。
注意:本题相对书上原题稍作改动
输入:
[
[-1,0],
[0,-1]
]
输出:[0,1,0,1]
题源:https://leetcode-cn.com/problems/max-submatrix-lcci/
参考:
53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。这是一个简单的dp问题
1、状态定义:dp[i]为以nums[i]结尾的最大子序和
2、状态转移方程:对于nums[i]有两种情况:一种是和前一个位置的子序列连着dp[i]=dp[i-1]+nums[i]
第二种是以自己独立门户,从自己开始dp[i]=nums[i]
取其中最大值,可得状态转移方程为dp[i]=max( dp[i-1] + nums[i] , nums[i] )
3、basecase:dp[0]=nums[0]很好理解
学习点:
1、vector<int> 可以用 ={ 1,2,3} 直接赋值
class Solution { public: vector<int> getMaxMatrix(vector<vector<int>>& matrix) { int n=matrix.size(); int m=matrix[0].size(); vector<vector<int>> f(n+1,vector<int>(m+1,0)); for(int j=0;j<m;j++) //每列前缀和 for(int i=0;i<n;i++) if (i>0) f[i][j]=f[i-1][j]+matrix[i][j]; else f[i][j]=matrix[i][j]; int res=-0x7fffffff; vector<int> ress; int b[205]; for (int i=0;i<n;i++) //枚举矩阵的上下边界 for(int j=i;j<n;j++) { int iy=0,sum=0; for(int k=0;k<m;k++) //枚举结束的列坐标 { if (i>0) b[k]=f[j][k]-f[i-1][k]; else b[k]=f[j][k]; if(sum+b[k]>=b[k]) sum=sum+b[k]; //sum记录了,以k列结尾的,最大子序列和,原来使用dp[i]记录,由于本题不需要记录 else { sum=b[k]; iy=k; } if (sum>=res) { res=sum; ress={i,iy,j,k}; } } } return ress; } };