题目:
给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。
题目数据保证总会存在一个数值和不超过 k 的矩形区域。
思路:
Sr=cursum ,固定r,去求满足条件的最小的Sl
idx = bisect.bisect_left(presum, cur_sum - k) 且idx<len(presum):确保满足条件Sr-k<=Sl。
若idx==len(presum),则上述条件无法满足。
解答:
适用:列数远大于行数
上下边界确定后,求每一列的值
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): #ru为上边界
col_sum = [0 for _ in range(Col)] #ru为上边界,rd为下边界,各列的和
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) #第一个大于等于cur_sum - k的值的index
if idx < len(presum):
res = max(res, cur_sum - presum[idx])
if res==k:
return k
bisect.insort(presum, cur_sum)
return res
进阶:行数远大于列数,那就枚举列比较合适一些
左右边界确定后,求每一行的值
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 L in range(Col): #L为左边界
row_sum = [0 for _ in range(Row)] #L为左边界R为右边界,各行的和
for R in range(L, Col):
for r in range(Row):
if matrix[r][R]==k:
return k
row_sum[r] += matrix[r][R]
presum = [0] #前缀和
cur_sum = 0 #当前的前缀和
for rowsum in row_sum:
cur_sum += rowsum
#idx:第一个大于等于cur_sum - k的值的index
idx = bisect.bisect_left(presum, cur_sum - k)
#如果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