class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
}
};
363. 矩形区域不超过 K 的最大数值和
给你一个 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
进阶:如果行数远大于列数,该如何设计解决方案?
原站题解
golang 解法, 执行用时: 272 ms, 内存消耗: 7.3 MB, 提交时间: 2023-10-08 22:59:36
import "math/rand" type node struct { ch [2]*node priority int val int } func (o *node) cmp(b int) int { switch { case b < o.val: return 0 case b > o.val: return 1 default: return -1 } } func (o *node) rotate(d int) *node { x := o.ch[d^1] o.ch[d^1] = x.ch[d] x.ch[d] = o return x } type treap struct { root *node } func (t *treap) _put(o *node, val int) *node { if o == nil { return &node{priority: rand.Int(), val: val} } if d := o.cmp(val); d >= 0 { o.ch[d] = t._put(o.ch[d], val) if o.ch[d].priority > o.priority { o = o.rotate(d ^ 1) } } return o } func (t *treap) put(val int) { t.root = t._put(t.root, val) } func (t *treap) lowerBound(val int) (lb *node) { for o := t.root; o != nil; { switch c := o.cmp(val); { case c == 0: lb = o o = o.ch[0] case c > 0: o = o.ch[1] default: return o } } return } func maxSumSubmatrix(matrix [][]int, k int) int { ans := math.MinInt64 for i := range matrix { // 枚举上边界 sum := make([]int, len(matrix[0])) for _, row := range matrix[i:] { // 枚举下边界 for c, v := range row { sum[c] += v // 更新每列的元素和 } t := &treap{} t.put(0) s := 0 for _, v := range sum { s += v if lb := t.lowerBound(s - k); lb != nil { ans = max(ans, s-lb.val) } t.put(s) } } } return ans } func max(a, b int) int { if a > b { return a } return b }
python3 解法, 执行用时: 3932 ms, 内存消耗: 17 MB, 提交时间: 2023-10-08 22:59:23
from sortedcontainers import SortedList class Solution: def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int: ans = float("-inf") m, n = len(matrix), len(matrix[0]) for i in range(m): # 枚举上边界 total = [0] * n for j in range(i, m): # 枚举下边界 for c in range(n): total[c] += matrix[j][c] # 更新每列的元素和 totalSet = SortedList([0]) s = 0 for v in total: s += v lb = totalSet.bisect_left(s - k) if lb != len(totalSet): ans = max(ans, s - totalSet[lb]) totalSet.add(s) return ans
java 解法, 执行用时: 314 ms, 内存消耗: 42.1 MB, 提交时间: 2023-10-08 22:59:12
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; } }
cpp 解法, 执行用时: 904 ms, 内存消耗: 233 MB, 提交时间: 2023-10-08 22:59:00
class Solution { public: int maxSumSubmatrix(vector<vector<int>> &matrix, int k) { int ans = INT_MIN; int m = matrix.size(), n = matrix[0].size(); for (int i = 0; i < m; ++i) { // 枚举上边界 vector<int> sum(n); for (int j = i; j < m; ++j) { // 枚举下边界 for (int c = 0; c < n; ++c) { sum[c] += matrix[j][c]; // 更新每列的元素和 } set<int> sumSet{0}; int s = 0; for (int v : sum) { s += v; auto lb = sumSet.lower_bound(s - k); if (lb != sumSet.end()) { ans = max(ans, s - *lb); } sumSet.insert(s); } } } return ans; } };