1

0.一维前缀和

比较简单,就不写了,计算一个累计和数组sums,然后
i到j之间的和就等于sums[j]-sums[i]

1.二维前缀和

image.png

对于这么一个图,怎么快速计算,矩形内的和?

已知 dp[i][j] 必定包含一个元素 mat[i][j],假设我们已经计算出部分前缀和 dp[x][y](x < i 且 y < j),那么 dp[i][j] = mat[i][j] + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1]。
(图里忘记写减去重复的区域了)

WechatIMG153.jpeg

代码如下:

class Solution(object):
    def maxSideLength(self, mat):
        """
        :type mat: List[List[int]]
        :type threshold: int
        :rtype: int
        """
        m,n = len(mat),len(mat[0])

        sum_matrix = [[0]*(n+1) for _ in range(m+1)]

        for i in range(1,m+1):
            for j in range(1,n+1):
                sum_matrix[i][j] = mat[i-1][j-1] + sum_matrix[i-1][j] + sum_matrix[i][j-1] - sum_matrix[i-1][j-1]

        return sum_matrix

那么如果要求一个矩形内的和,他的左上坐标为(i0,j0),右下坐标为(i1,j1)那么这个该怎么求呢?
其实思路是刚好反过来的。
WechatIMG154.jpeg

完整的代码

maxSideLength 求从原点到每个位置的矩形和
getSubSquareArea求从(i0,j0)到(i1,j1)的矩形和

class Solution(object):

def maximalSquare(self, matrix):
    """
    :type matrix: List[List[str]]
    :rtype: int
    """

    def maxSideLength(mat):
        """
        :type mat: List[List[str]]
        :rtype: List
        """
        m, n = len(mat), len(mat[0])

        sum_matrix = [[0] * (n + 1) for _ in range(m + 1)]

        for i in range(1, m + 1):
            for j in range(1, n + 1):
                sum_matrix[i][j] = int(mat[i - 1][j - 1]) + sum_matrix[i - 1][j] + sum_matrix[i][j - 1] - \
                                   sum_matrix[i - 1][j - 1]

        return sum_matrix

    def getSubSquareArea(i0,j0,i1,j1):
        if i1<i0 or j1<j0:return 0
        return sum_matrix[i1+1][j1+1]-sum_matrix[i0][j1+1]-sum_matrix[i1+1][j0]+sum_matrix[i0][j0]
        
    sum_matrix = maxSideLength(matrix)
    return getSubSquareArea(1,2,2,4)

对于这么一个输入

[["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]

image.png

以上代码的执行结果应该为6


北语张益达
6 声望4 粉丝