leetcode 17.24. 最大子矩阵

给定一个正整数、负整数和 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
链接:https://leetcode.cn/problems/max-submatrix-lcci

思路:直接用最暴力的算法,计算 (i,j) 为 开头的节点的最大矩阵(m 行 n 列),这样时间复杂度是 mnmnm*n (在找一个 矩阵尾结点,然后矩阵内元素相加),那有没有更加单的方法呢?
其实最暴力的算法,矩阵内元素相加是可以做一些优化的,比如当前已经计算好了 (r1, c1) 开头,(r2, c2) 结束的子矩阵的和,那我们计算 (r1, c1) 开头,(r2, c2+1) 的时候就不用完全重新计算了。
类似的思路 如果需要计算从 第 i 行到 第 j 行最大子矩阵的和,因为行限定了,只是矩阵的列不一样,联想到最大连续子数组和,我们可以把 第 i 行到第 j 行同一列不同行的元素相加到一起,这样就转换成最大连续子数组和的问题了

class Solution:
    def getMaxMatrix(self, matrix: List[List[int]]) -> List[int]:
        rows, cols = len(matrix), len(matrix[0])
        maxSum = -(pow(2,31)-1)
        res = [-1, -1, -1, -1]
        r1, c1, r2, c2 = 0, 0, 0, 0
        for i in range(rows):
            a = [0 for k in range(cols)] ## 存同一列从i 行到 j 行个元素的累加值
            r1 = i  ## 矩阵从第i 行开始计算
            for j in range(i, rows):
                sum = 0
                c1 = 0 
                r2 = j   ## 矩阵从 i 行 到 j 行 某些列累加
                for k in range(cols):
                    a[k] += matrix[j][k]
                    if sum >= 0:   ## sum 表示到当前第 k列为止的最大和
                        sum += a[k]
                    else:
                        sum = a[k]
                        c1 = k ## 更新 c1 开始的列
                    if sum > maxSum:
                        c2 = k
                        res[0], res[1], res[2], res[3] = r1, c1, r2, c2
                        maxSum = sum
        return res
                

你可能感兴趣的:(动态规划,编程与算法,LeetCode,leetcode,矩阵,算法)