作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址: https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/description/

题目描述:

Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.

Example:

Input: matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
Explanation: Because the sum of rectangle [[0, 1], [-2, 3]] is 2,
and 2 is the max number no larger than k (k = 2).

Note:

  1. The rectangle inside the matrix must have an area > 0.
  2. What if the number of rows is much larger than the number of columns?

题目大意

找出一个矩阵中的子长方形,使得这个长方形的和是最大的。

解题方法

方法一:暴力求解(TLE)

求和最大的矩形,很容易让人想到先把(0, 0)到所有(i, j)位置的矩形的和求出来,然后再次遍历,求出所有子矩形中和最大的那个。

很无奈,超时了。(好像C++可以通过,python伤不起)

时间复杂度是O((MN)^2),空间复杂度是O(MN)。

class Solution(object):
def maxSumSubmatrix(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
if not matrix or not matrix[0]: return 0
M, N = len(matrix), len(matrix[0])
sums = [[0] * N for _ in range(M)]
res = float("-inf")
for m in range(M):
for n in range(N):
t = matrix[m][n]
if m > 0:
t += sums[m - 1][n]
if n > 0:
t += sums[m][n - 1]
if m > 0 and n > 0:
t -= sums[m - 1][n - 1]
sums[m][n] = t
for r in range(m + 1):
for c in range(n + 1):
d = sums[m][n]
if r > 0:
d -= sums[r - 1][n]
if c > 0:
d -= sums[m][c - 1]
if r > 0 and c > 0:
d += sums[r - 1][c - 1]
if d <= k:
res = max(res, d)
return res

方法二:Kadane’s algorithm (TLE)

看了印度小哥的视频,真的很好理解,告诉我们使用一个数组的情况下,如何找出整个二维子矩阵的最大值。我看了视频之后,写出了这个算法,但是很无奈,直接用这个算法仍然超时。

我分析,这个算法时间复杂度仍然没有降下来,主要问题是获取子数组的最大区间和这一步太耗时了。

时间复杂度是O((MN)^2),空间复杂度是O(M)。

class Solution(object):
def maxSumSubmatrix(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
if not matrix or not matrix[0]: return 0
L, R = 0, 0
curSum, maxSum = float('-inf'), float('-inf')
maxLeft, maxRight, maxUp, maxDown = 0, 0, 0, 0
M, N = len(matrix), len(matrix[0])
for L in range(N):
curArr = [0] * M
for R in range(L, N):
for m in range(M):
curArr[m] += matrix[m][R]
curSum = self.getSumArray(curArr, M, k)
if curSum > maxSum:
maxSum = curSum
return maxSum def getSumArray(self, arr, M, k):
sums = [0] * (M + 1)
for i in range(M):
sums[i + 1] = arr[i] + sums[i]
res = float('-inf')
for i in range(M):
for j in range(i + 1, M + 1):
curSum = sums[j] - sums[i]
if curSum <= k and curSum > res:
res = curSum
return res

方法二:Kadane’s algorithm + 二分查找 (Accepted)

上面的算法慢就慢在查找子数组的最大和部分。其实没必要使用求最大和的方式。因为题目要求我们找出不超过K的和,所以只需要在数组中是否存在另外一个数使得两者的差不超过K即可。这个查找的效率能达到O(NlogN).

在C++中能使用set和lowwer_bound实现,在python中使用bisect_left函数能也实现。

这个过程可以在这个文章中看到更详细的说明。

在时间复杂度中可以看到M影响更大,另外一个优化的策略是重新设置矩形的长和宽,这样也可以优化速度。

时间复杂度是O(MNMlogM),空间复杂度是O(M)。

class Solution(object):
def maxSumSubmatrix(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
m = len(matrix)
n = len(matrix[0]) if m else 0 M = max(m, n)
N = min(m, n)
ans = None
for x in range(N):
sums = [0] * M
for y in range(x, N):
slist, num = [], 0
for z in range(M):
sums[z] += matrix[z][y] if m > n else matrix[y][z]
num += sums[z]
if num <= k:
ans = max(ans, num)
i = bisect.bisect_left(slist, num - k)
if i != len(slist):
ans = max(ans, num - slist[i])
bisect.insort(slist, num)
return ans or 0

参考资料:

http://bookshadow.com/weblog/2016/06/22/leetcode-max-sum-of-sub-matrix-no-larger-than-k/
http://www.cnblogs.com/grandyang/p/5617660.html
https://www.quora.com/Given-an-array-of-integers-A-and-an-integer-k-find-a-subarray-that-contains-the-largest-sum-subject-to-a-constraint-that-the-sum-is-less-than-k
https://www.youtube.com/watch?v=yCQN096CwWM&t=589s

日期

2018 年 10 月 11 日 —— 做Hard题真的很难

【LeetCode】363. Max Sum of Rectangle No Larger Than K 解题报告(Python)的更多相关文章

  1. [LeetCode] 363. Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  2. 第十三周 Leetcode 363. Max Sum of Rectangle No Larger Than K(HARD)

    Leetcode363 思路: 一种naive的算法就是枚举每个矩形块, 时间复杂度为O((mn)^2), 可以做少许优化时间复杂度可以降低到O(mnnlogm), 其中m为行数, n为列数. 先求出 ...

  3. 363. Max Sum of Rectangle No Larger Than K

    /* * 363. Max Sum of Rectangle No Larger Than K * 2016-7-15 by Mingyang */ public int maxSumSubmatri ...

  4. 【leetcode】363. Max Sum of Rectangle No Larger Than K

    题目描述: Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the ma ...

  5. 363 Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  6. [LeetCode] Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  7. Leetcode: Max Sum of Rectangle No Larger Than K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  8. [Swift]LeetCode363. 矩形区域不超过 K 的最大数值和 | Max Sum of Rectangle No Larger Than K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  9. Max Sum of Rectangle No Larger Than K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

随机推荐

  1. R语言与医学统计图形-【12】ggplot2几何对象之条图

    ggplot2绘图系统--几何对象之条图(包括误差条图) 1.条图 格式: geom_bar(mapping = , data = , stat = 'count', #统计变换默认计数 positi ...

  2. js变量作为数组对象的键值方法

    js变量作为数组对象的键值方法,变量键值获取数组值 js也可以像php的数组一样用下标获取数组的值,方法是: var arr = {'key':'abc'}; var key = 'key'; con ...

  3. day08 外键字段的增删查改

    day08 外键字段的增删查改 今日内容概要 外键字段的增删查改 正反向查询的概念 基于对象的跨表查询(子查询) 基于双下划线的跨表查询(连表操作) 聚合查询与分组查询 F查询和Q查询 前提准备 cl ...

  4. 【leetcode】122.Best Time to Buy and Sell Stock II(股票问题)

    You are given an integer array prices where prices[i] is the price of a given stock on the ith day. ...

  5. JavaIO——内存操作流、打印流

    我们之前所做的都是对文件进行IO处理,实则我们也可以对内存进行IO处理.我们将发生在内存中的IO处理称为内存流. 内存操作流也可分为两类:字节内存流和字符内存流. (1)ByteArrayInputS ...

  6. Vue API 3模板语法 ,指令

    条件# v-if# v-if 指令用于条件性地渲染一块内容.这块内容只会在指令的表达式返回 truthy 值的时候被渲染. v-show# v-show 指令也是用于根据条件展示一块内容.v-show ...

  7. adb命令对app进行测试

    1.何为adb adb android  debug  bridge ,sdk包中的工具,将Platform-tooks 和tools  两个路径配置到环境变量中 2.SDK下载链接:http://t ...

  8. 【Services】【Web】【apr】安装apr

    1. 基础: 1.1 描述:apr全称Apache Portable Runtime,常用于与ssl相关的环境支持,比如openssl,httpd,nginx,tomcat 1.2 链接: 官方网站: ...

  9. js 长按鼠标左键实现溢出内容左右滚动滚动

    var nextPress, prevPress; // 鼠标按下执行定时器,每0.1秒向左移一个li内容的宽度 function nextDown() { nextPress = setInterv ...

  10. 【Java基础】transient关键字

    1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...