Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.
Note:
- The rectangle inside the matrix must have an area > 0. (1 也算)
- What if the number of rows is much larger than the number of columns?
最大子序列问题的二维扩展版本。直接Brute Force。
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int height = matrix.size();
int width = matrix[0].size();
int currentmax = INT_MIN; //numeric_limits<int>::min();
vector<vector<int>> sum(height, vector<int>(width,0));
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
if(i>0){sum[i][j] += sum[i-1][j];}
if(j>0){sum[i][j] += sum[i][j-1];}
if(i>0 && j>0){sum[i][j] -= sum[i-1][j-1];}
sum[i][j] += matrix[i][j];// 二维矩阵求和matrix[0:i][0:j],利用已经计算出的矩阵
for(int r=0;r<=i;r++){
for(int m=0;m<=j;m++){
int res = sum[i][j];
if(r>0) res -= sum[r-1][j];
if(m>0) res -= sum[i][m-1];
if(r>0 && m>0){res += sum[r-1][m-1];}//二维子矩阵求和matrix[r:i][m:j],利用已经计算出的矩阵
if(res<=k && res>currentmax) currentmax = res;
}
}
}
}
return currentmax;
}
};
hints:Jay kadane: 可以用二维的kadane 算法进一步优化,但是不用也可以在时间复杂度要求范围内解决问题。
一维的kadane 算法用来计算最大子序列(长度>0):线性优于n^2 有时候要考虑至少要有一个正数。
e.g. matrix [-3, 2, -1, 4]
step1: sum[0:0] -3; currentmax = -3; globbalmax = -3
step2: sum[0:1] currentmax = currentmax+matrix[1] >matrix[1]? -3+2:2; currentmax = 2; globbalmax = 2
step3: sum[0:2] currentmax = currentmax+matrix[2] >matrix[2]? 2+-1:-1; currentmax = 1; globbalmax = 2
step3: sum[0:3] currentmax = currentmax+matrix[3]>matrix[3]? 1+4:4; currentmax = 5; globbalmax = 5
证明也很简单,假设存在另外一个最大,证伪。
二维的kadane 算法用来计算最大子序列(长度>0)过程太复杂,自己搜吧。
https://www.youtube.com/watch?v=yCQN096CwWM&t=527s
六个变量,上下左右位置标志,currentmax and globbalmax. 仍然是利用二维子序列连通性。
先搞一个辅助一维列序列,然后思想和brute force 差不多,好处是用一维的算法少了一些计算。