Input:
matrix = [[1,0,1],[0,-2,3]], k = 2
Output:
2
Explanation: Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
We reduce the 2D problem to a series of 1D subarray sum problems by fixing two rows and compressing the columns between them. For each compressed array, we use prefix sums and binary search to find the max subarray sum no larger than k.
classSolution {
public:int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int m = matrix.size(), n = matrix[0].size(), ans = INT_MIN;
for (int top =0; top < m; ++top) {
vector<int> colSum(n);
for (int bottom = top; bottom < m; ++bottom) {
for (int j =0; j < n; ++j) colSum[j] += matrix[bottom][j];
set<int> s = {0};
int sum =0;
for (int x : colSum) {
sum += x;
auto it = s.lower_bound(sum - k);
if (it != s.end()) ans = max(ans, sum -*it);
s.insert(sum);
}
}
}
return ans;
}
};
classSolution {
publicintmaxSumSubmatrix(int[][] matrix, int k) {
int m = matrix.length, n = matrix[0].length, ans = Integer.MIN_VALUE;
for (int top = 0; top < m; ++top) {
int[] colSum =newint[n];
for (int bottom = top; bottom < m; ++bottom) {
for (int j = 0; j < n; ++j) colSum[j]+= matrix[bottom][j];
TreeSet<Integer> s =new TreeSet<>();
s.add(0);
int sum = 0;
for (int x : colSum) {
sum += x;
Integer it = s.ceiling(sum - k);
if (it !=null) ans = Math.max(ans, sum - it);
s.add(sum);
}
}
}
return ans;
}
}
classSolution {
funmaxSumSubmatrix(matrix: Array<IntArray>, k: Int): Int {
val m = matrix.size
val n = matrix[0].size
var ans = Int.MIN_VALUE
for (top in0 until m) {
val colSum = IntArray(n)
for (bottom in top until m) {
for (j in0 until n) colSum[j] += matrix[bottom][j]
val s = java.util.TreeSet<Int>()
s.add(0)
var sum = 0for (x in colSum) {
sum += x
val it = s.ceiling(sum - k)
if (it!=null) ans = maxOf(ans, sum - it)
s.add(sum)
}
}
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defmaxSumSubmatrix(self, matrix: list[list[int]], k: int) -> int:
m, n = len(matrix), len(matrix[0])
ans = float('-inf')
for top in range(m):
col_sum = [0] * n
for bottom in range(top, m):
for j in range(n):
col_sum[j] += matrix[bottom][j]
s = [0]
curr_sum =0for x in col_sum:
curr_sum += x
idx = bisect_left(s, curr_sum - k)
if idx < len(s):
ans = max(ans, curr_sum - s[idx])
insort(s, curr_sum)
return ans