leetcode每日一题—363. 矩形区域不超过 K 的最大数值和

461 篇文章 1 订阅
该博客介绍了如何在给定的矩阵中找到数值和不超过k的最大矩形区域。通过固定矩阵的某一边界,计算另一边界的前缀和,并使用二分查找法确定满足条件的子矩阵。算法适用于列数远大于行数或行数远大于列数的情况。此外,还提供了优化的解决方案,分别针对不同情况枚举行或列来提高效率。
摘要由CSDN通过智能技术生成

题目:
给你一个 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值