Leetcode[17.24 最大子矩阵]

0. 题目

给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。

返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。

注意:本题相对书上原题稍作改动

示例:

输入:
[
[-1,0],
[0,-1]
]
输出:[0,1,0,1]
解释:输入中标粗的元素即为输出所表示的矩阵

说明:

1 <= matrix.length, matrix[0].length <= 200

1. 题解

a. 暴力

直接使用暴力求解,依次枚举左上、左下、右上、右下坐标,
之后求和Matrix[左上x:右下x][左上y:右下y],
得到当前值temp,若temp>MaxValue,则更新MaxValue与坐标ans

class Solution:
    def getMaxMatrix(self, matrix: List[List[int]]) -> List[int]:
        m=len(matrix) 
        n=len(matrix[0])
        MaxValue=-float('inf')
        ans=[0,0,0,0]
        for l1 in range(m): #枚举左上点的x
            for l2 in range(n): #枚举左上点的y
                for r1 in range(l1,m): #枚举右下x
                    for r2 in range(l2,n): #枚举右下y
                        temp=0 
                        #计算当前子矩阵的和
                        for i in range(l1,r1+1):
                            for j in range(l2,r2+1):
                                temp+=matrix[i][j]
                        #如果子矩阵的值大于之前的最大值,则renew MaxValue和ans
                        if temp>MaxValue:
                            MaxValue=temp
                            ans=[l1,l2,r1,r2]
        return ans

暴力求解,时间复杂度为O((m*n)^3),空间复杂度O(1),会TLE

b.前缀+dp

将二维问题降维,转化为一维最大子序列的问题
时间复杂度O((m*n)^2),空间复杂度O(n)

class Solution:
    def getMaxMatrix(self, matrix: List[List[int]]) -> List[int]:
        m,n=len(matrix),len(matrix[0])
        ans=[0]*4
        MaxValue=-float('inf')
        for i in range(m): #从第i行开始
            for j in range(i,m): #以第j行结尾
            	temp=[0]*n #存储i到j行的前缀和
                begin=0 #子序列开始的位置
                dp=0 #dp的初始值
                #计算从第i行到第j行的前缀和temp[n](共n列),!此步骤有大量的重复运算!
                for k in range(n):
                	for l in range(i,j+1)
                    	temp[k]+=matrix[l][k]
                    #求解最大子序列
                    if dp<0:
                        dp=temp[k]
                        begin=k
                    else:
                        dp=dp+temp[k]
                    if dp>MaxValue:
                        MaxValue=dp
                        ans=i,begin,j,k
        return ans

c.前缀+dp+优化

将二维问题降维,转化为一维最大子序列问题
b方法中,我们可以明显感受到,在计算每一列的和时有大量的重复计算,我们对此进行优化,将计算过的值存储下来以复用
时间复杂度O(m^2*n),空间复杂度O(n)

class Solution:
    def getMaxMatrix(self, matrix: List[List[int]]) -> List[int]:
        m,n=len(matrix),len(matrix[0])
        ans=[0]*4
        MaxValue=-float('inf')
        for i in range(m): 
            temp=[0]*n #如果起始行不变,就没必要从零开始计算,可以把之前行的和存储起来
            for j in range(i,m):
                begin=0 #起始位置清0
                dp=0 #dp清0
                for k in range(n):
                    temp[k]+=matrix[j][k]
	                if dp<0:
	                    dp=temp[k]
	                    begin=k
	                else:
	                    dp=dp+temp[k]
	                if dp>MaxValue:
	                    MaxValue=dp
	                    ans=i,begin,j,k
        return ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值