【DP】最大正方形

题源
出现的问题:

  1. 没有正确地理解和应用DP思想,一开始想着转移dp[i-1][j-1]的方法是扫描dp[i-1][j-1]dp[i][j]中间所有多出来的矩阵格子,但是这样时间效率太差,而且还容易写错
  2. 没有正确地转移,只考虑了dp[i-1][j-1]dp[i][j],没有考虑dp[i-1][j]和dp[i][j-1],正确的思路是如果dp[i][j]的值是 1,则 dp[i][j]的值由其上方dp[i-1][j]、左方dp[i][j-1]和左上方dp[i-1][j-1的三个相邻位置的 dp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 1
  3. dp[i-1][j-1]dp[i-1][j]和dp[i][j-1]大而且非零时,我原来的算法会引发灾难性的问题,简单来说就是计算多出来的格子的时候起始位置太靠前了,导致碰到了零,然后就正方形判定失败了,但其实如果用保守点的值,dp[i-1][j]和dp[i][j-1],的话,是没有问题的,这就是为什么需要min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])

正确解答:

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if not matrix or not matrix[0]:
            return 0
        
        m, n = len(matrix), len(matrix[0])
        max_side = 0
        dp = [[0] * n for _ in range(m)]
        

        for i in range(m):
            for j in range(n):
                if matrix[i][j] == "1":
                    dp[i][j] = 1
                    max_side = max(max_side, 1)
        

        for i in range(1, m): 
            for j in range(1, n): 
                if matrix[i][j] == "1":
                    dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
                    max_side = max(max_side, dp[i][j])
                    
        return max_side * max_side

错误解答:

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        m = len(matrix)
        n = len(matrix[0])
        max_side = 0
        dp = [[0] * n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                dp[i][j] = 1 if matrix[i][j] == "1" else 0
                max_side = max(max_side, dp[i][j])
        
        for i in range(m):
            for j in range(n):
                i_ = i - 1
                j_ = j - 1
                if i_ >= 0 and j_ >= 0 and dp[i_][j_] != 0 and dp[i][j] != 0:
                    flag = True
                    attemped_side = dp[i-1][j-1] 
                    for k in range(j-attemped_side, j):
                        if i == 4: print(matrix[i][k])
                        if matrix[i][k] == "0": 
                            flag = False
                            break
                    for k in range(i-attemped_side, i):
                        if j == 4: print(matrix[k][j])
                        if matrix[k][j] == "0":
                            flag = False
                            break
                    if flag == True:
                        dp[i][j] = dp[i_][j_] + 1
                        max_side = max(max_side, dp[i][j])
        return max_side * max_side
                    
posted @ 2024-05-04 02:21  peterzh6  阅读(6)  评论(0编辑  收藏  举报