Given a non-empty 2D matrix Matrix and an integer K, find the max sum of a rectangle in the matrix such that it sum is no larger than K.
Example:
Given matrix = [ [1, 0, 1], [0,-2, 3]]k = 2
The answer is 2
. Because The sum of rectangle is 2 and 2 is the [[0, 1], [-2, 3]]
max number no larger than k (k = 2).
Note:
- The rectangle inside the matrix must has an area > 0.
- What if the number of rows is much larger than the number of columns?
Credits:
Special thanks to @fujiaozhu for adding this problem and creating all test cases.
This problem gives us a two-dimensional array, let us sum not more than the largest sub-rectangle of K, then we can first consider using brute force to solve, is to traverse all the sub-rectangles, and then calculate and compare with the K, find not more than the maximum value of K. Even if it is a brute force search, we can also use optimized algorithms, such as build up summation and, see the previous question range Sum Query 2d-immutable, we can quickly find any interval and, then the following method is so, when traversing to (I, j), we calculate Sum ( I, J), which represents the and of the rectangle (0, 0) to (i, j), and then we traverse all the sub-rectangles in the rectangle, calculating it and comparing it with the K, so that it can traverse all the sub-rectangles of the original rectangle, see the code as follows:
Solution One:
classSolution { Public: intMaxsumsubmatrix (vector<vector<int>>& Matrix,intk) {if(Matrix.empty () | | matrix[0].empty ())return 0; intm = Matrix.size (), n = matrix[0].size (), res =int_min; intSum[m][n]; for(inti =0; I < m; ++i) { for(intj =0; J < N; ++j) {intt =Matrix[i][j]; if(I >0) T + = sum[i-1][j]; if(J >0) T + = sum[i][j-1]; if(I >0&& J >0) T-= sum[i-1][j-1]; SUM[I][J]=T; for(intR =0; R <= I; ++r) { for(intc =0; C <= J; ++c) {intD =Sum[i][j]; if(R >0) D-= Sum[r-1][j]; if(C >0) D-= Sum[i][c-1]; if(R >0&& C >0) d + = Sum[r-1][c-1]; if(d <= k) res =Max (res, d); } } } } returnRes; }};
The following algorithm further optimizes the run time, which is based on the calculation of the largest sub-matrix in a two-dimensional array and the algorithm, you can see this video on YouTube maximum Sum rectangular submatrix in Matrix dynamic Programming/2d Kadane. This algorithm cleverly in the two-dimensional array of rows or columns into multiple one-dimensional array, and then use the sum of one-dimensional array to find the number of matching requirements, here with lower_bound to speed up our search speed, can also use the binary search method to replace. We set up a set, then we start putting a 0 in, why we put 0, because we want to find Lower_bound (cursum-k), when Cursum and K are equal, 0 can be returned, so we can update the results. Since we have accumulated the sum of one-dimensional arrays, then sum[i,j] = sum[i]-sum[j], where SUMS[I,J] is the target sub-array needs it and is less than or equal to K, then Sums[j] is cursum, and sum[i] is what we are looking for value, When we use the binary search method to find Sum[i], sum[i] and need to >=sum[j]-K, so you can also use Lower_bound to find, see the code is as follows:
Solution Two:
classSolution { Public: intMaxsumsubmatrix (vector<vector<int>>& Matrix,intk) {if(Matrix.empty () | | matrix[0].empty ())return 0; intm = Matrix.size (), n = matrix[0].size (), res =int_min; for(inti =0; I < n; ++i) {vector<int> Sum (M,0); for(intj = i; J < N; ++j) { for(intK =0; K < M; ++k) {Sum[k]+=Matrix[k][j]; } intCursum =0, Curmax =int_min; Set<int>s; S.insert (0); for(Auto a:sum) {cursum+=A; Auto It= S.lower_bound (Cursum-k); if(It! = S.end ()) Curmax = Max (Curmax, Cursum-*it); S.insert (cursum); } Res=Max (res, curmax); } } returnRes; }};
Similar topics:
Maximum Subarray
Range Sum Query 2d-immutable
Maximum Size subarray Sum Equals k
Resources:
Https://leetcode.com/discuss/109847/2-accepted-java-solution
Https://leetcode.com/discuss/109749/accepted-c-codes-with-explanation-and-references
Leetcode all in one topic summary (continuous update ...)
[Leetcode] Max Sum of Rectangle no Larger Than k max Matrix and no more than K