此题解采用了前缀和加二分查找的方法来解决问题。首先,我们遍历所有可能的上下边界组合,然后计算这个边界内每一列的和,并将其保存在col_sum数组中。接着,我们利用前缀和的概念来计算从第一列到当前列的所有元素的和,存储在cur_sum中。为了找到一个子矩阵的和不超过k,我们需要在presum数组中查找一个数,使得cur_sum减去这个数不超过k。我们使用二分查找来快速定位这个数,如果找到了满足条件的子矩阵,我们就更新结果res。最终,返回res即可。
时间复杂度: O(m^2 * n * logn)
空间复杂度: O(n)
import bisect
class Solution:
def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
m = len(matrix)
Row, Col = len(matrix), len(matrix[0])
res = float('-inf')
for ru in range(Row):
col_sum = [0 for _ in range(Col)]
for rd in range(ru, Row):
for c in range(Col):
if matrix[rd][c] == k:
return k
col_sum[c] += matrix[rd][c]
presum = [0]
cur_sum = 0
for colsum in col_sum:
cur_sum += colsum
idx = bisect.bisect_left(presum, cur_sum - k)
if idx < len(presum):
res = max(res, cur_sum - presum[idx])
if res == k:
return k
bisect.insort(presum, cur_sum)
return res