一、问题描述
给你一个 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
三、解题思路
建立一个数组 int[] rowSum 存放每一行左边界至右边界的值,
将 rowSum 再次算矩形区域的值,分为上边界和下边界。最后得出不超过 k 的最大数值和.
例输入:[2,3,4,-10] , [-1,2,3,4] , [1,1,1,0] , [-3,0,8,9] k=1
则第一次循环 左边界 left = 0 ,右边界 right = 0
rowSum[row] | 0 | 1 | 2 | 3 |
---|---|---|---|---|
2 | 2 | 3 | 4 | -10 |
-1 | -1 | 2 | 3 | 4 |
1 | 1 | 1 | 1 | 0 |
-3 | -3 | 0 | 8 | 9 |
dpmax(int[] arr, int k) 函数返回值 为 1
该函数一样,分为上边界和下边界,
枚举矩形如:
- 2,2+ -1=1,2+ -1+1=2,2+ -1+1+ -3=-1;
- -1,-1+1=0,-1+1+ -3=-3;
- 1,1+ -3=-2
- -3
第二次循环:
rowSum[row] | 0 | 1 | 2 | 3 |
---|---|---|---|---|
2+3= 5 | 2 | 3 | 4 | -10 |
-1+2= 1 | -1 | 2 | 3 | 4 |
1+1= 2 | 1 | 1 | 1 | 0 |
-3+0= -3 | -3 | 0 | 8 | 9 |
…
四、java实现
class Solution {
public int maxSumSubmatrix(int[][] matrix, int k) {
int row = matrix.length;
if(row<=0) return 0;
int line = matrix[0].length;
int max = Integer.MIN_VALUE;
for(int left=0;left<line;left++){
int[] rowSum = new int[row];
for(int right=left;right<line;right++){
for(int i=0;i<row;i++){
rowSum[i]+= matrix[i][right];
}
max = Math.max(max,dpmax(rowSum,k));
}
}
return max;
}
// 在数组 arr 中,求不超过 k 的最大值
private int dpmax(int[] arr, int k) {
int max = Integer.MIN_VALUE;
int n = arr.length;
for (int top = 0; top < n; top++) {
int sum = 0;
for (int bottom = top; bottom < n; bottom++) {
sum += arr[bottom];
if (sum > max && sum <= k) max = sum;
}
}
return max;
}
}