给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。
题目数据保证总会存在一个数值和不超过 k 的矩形区域。
示例 1:
输入:matrix = [[1,0,1],[0,-2,3]], k = 2
输出:2
解释:蓝色边框圈出来的矩形区域 [[0, 1], [-2, 3]] 的数值和是 2,且 2 是不超过 k 的最大数字(k = 2)。
示例 2:
输入:matrix = [[2,2,-1]], k = 3
输出:3
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-100 <= matrix[i][j] <= 100
-105 <= k <= 105
进阶:如果行数远大于列数,该如何设计解决方案?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:说一下我自己一开始的想法(我只想了,没有去实现,因为官方的更好,有自己的思考就行了,再学习官方的)。
首先题目给了一个m * n的矩阵和目标值k,让我们在这个矩阵中弄一个小矩阵,这个小矩阵中的sum<=k(求sum的最大值)。
矩阵求和,第一思路就是前缀和,我们也创建一个m * n的数组来存放前缀和。然后遍历m * n(矩阵的长宽),再遍历前缀和数组,满足长宽的都计算一遍。在遍历m*n矩阵过程中,n遍历完,加个if(max==k)break;这个if在一些样例中可以尽量减少循环(捂脸)
放个官方的代码:
class Solution {
public int maxSumSubmatrix(int[][] matrix, int k) {
int ans = Integer.MIN_VALUE;
int m = matrix.length, n = matrix[0].length;
for (int i = 0; i < m; ++i) { // 枚举上边界
int[] sum = new int[n];
for (int j = i; j < m; ++j) { // 枚举下边界
for (int c = 0; c < n; ++c) {
sum[c] += matrix[j][c]; // 更新每列的元素和
}
TreeSet<Integer> sumSet = new TreeSet<Integer>();
sumSet.add(0);
int s = 0;
for (int v : sum) {
s += v;
Integer ceil = sumSet.ceiling(s - k);
if (ceil != null) {
ans = Math.max(ans, s - ceil);
}
sumSet.add(s);
}
}
}
return ans;
}
}