题目链接: https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k
难度:困难
通过率:34.1%
题目描述:
给定一个非空二维矩阵 matrix _和一个整数 _k ,找到这个矩阵内部不大于 k 的最大矩形和。
示例:
示例:
输入: matrix = [[1,0,1],[0,-2,3]], k = 2 输出: 2 解释: 矩形区域 [[0, 1], [-2, 3]] 的数值和是 2,且 2 是不超过 k 的最大数字(k = 2)。
说明:
- 矩阵内的矩形区域面积必须大于 0。
- 如果行数远大于列数,你将如何解答呢?
思路:
做这道题之前,做一下 53. 最大子序和 | 题解链接
对,关键思想就是前缀和
我们先把题目转化一下,求矩阵连续行组成面积最大?什么意思呢?就是固定左右边界,只考虑行,在哪两个行之间组成矩形的面积最大。
这样我们就可以通过前缀和的方式,我们把每行的总和求得,通过前缀和的找差值最大就能找到最大矩阵了!
那么我们这题说不超过K的最大数值和,也就是找到的矩阵尽可能的和接近K,有了前缀和数组还能找不到吗?
所以,我们代码如下:
- 划分左右边界,并求出在此边界下,每行的总和
- 通过二分法找不超过K的矩阵
当然以行划分也行,为什么要以列为边界,因为题目中说了 如果行数远大于列数呢!
class Solution:
def maxSumSubmatrix(self, matrix: List[List[int]], k: int) -> int:
import bisect
row = len(matrix)
col = len(matrix[0])
res = float("-inf")
for left in range(col):
# 以left为左边界,每行的总和
_sum = [0] * row
for right in range(left, col):
for j in range(row):
_sum[j] += matrix[j][right]
# 在left,right为边界下的矩阵,求不超过K的最大数值和
arr = [0]
cur = 0
for tmp in _sum:
cur += tmp
# 二分法
loc = bisect.bisect_left(arr, cur - k)
if loc < len(arr):res = max(cur - arr[loc], res)
# 把累加和加入
bisect.insort(arr, cur)
return res