Leetcode刷题笔记——多维动态规划篇

Leetcode刷题笔记——多维动态规划篇

第一题:最小路径和

Leetcode64:最小路径和:中等题 (详情点击链接见原题)

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小

python代码解法

class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])  # m 行 n 列
        dp_matrix = [[0] * n for _ in range(m)]
        dp_matrix[0][0] = grid[0][0]
        for i in range(1, n):  # dp数组初始化
            dp_matrix[0][i] = dp_matrix[0][i - 1] + grid[0][i]
        for j in range(1, m):
            dp_matrix[j][0] = dp_matrix[j - 1][0] + grid[j][0]
        
        for x in range(1, m):
            for y in range(1, n):
                dp_matrix[x][y] = min(dp_matrix[x][y - 1] + grid[x][y], dp_matrix[x - 1][y] + grid[x][y])
        # print(dp_matrix)
        return dp_matrix[m - 1][n - 1]

第二题:三角形最小路径和

Leetcode120. 三角形最小路径和:中等题 (详情点击链接见原题)

给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 ii + 1

python代码解法

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        dp = [[0 for _ in range(len(tri))] for tri in triangle]
        dp[0][0] = triangle[0][0]
        for i in range(1, len(triangle)):
            for j in range(0, len(triangle[i])):
                if 0 < j < len(triangle[i]) - 1:
                    dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]
                elif j == 0:
                    dp[i][j] = dp[i - 1][j] + triangle[i][j]
                else:
                    dp[i][j] = dp[i - 1][j - 1] + triangle[i][j]
        return min(dp[len(triangle) - 1])

第三题:不同路径

Leetcode62. 不同路径:中等题 (详情点击链接见原题)

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?

解题思路
机器人从(0 , 0) 位置出发,到 (m - 1, n - 1) 终点

1.确定 dp 数组(dp table)以及下标的含义
dp[i][j] :表示从(0 ,0)出发,到 (i, j)dp[i][j] 条不同的路径

2.确定递推公式
dp[i][j] 只能有两个方向来推导出来,即 dp[i - 1][j]dp[i][j - 1]dp[i - 1][j] 表示从 (0, 0) 的位置到 (i - 1, j) 有几条路径

3.dp数组如何初始化
dp[i][0]dp[0][j] 一定都是1,因为从 (0, 0) 的位置到 (i, 0)(0, j) 的路径只有一条

4.确定遍历顺序
递推公式 dp[i][j] = dp[i - 1][j] + dp[i][j - 1]dp[i][j] 都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了

5.举例推导 dp 数组
在这里插入图片描述

python代码解法

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[0] * n for _ in range(m)]

        # dp 数组初始化
        for row in range(m):
            dp[row][0] = 1
        for col in range(1, n):
            dp[0][col] = 1

        for row in range(1, m):
            for col in range(1, n):
                dp[row][col] = dp[row - 1][col] + dp[row][col - 1]
        return dp[m - 1][n - 1]

第四题:不同路径 II

Leetcode63. 不同路径 II:中等题 (详情点击链接见原题)

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

python代码解法

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        m, n = len(obstacleGrid), len(obstacleGrid[0])
        dp = [[0] * n for _ in range(m)]  # dp 数组初始化
        if obstacleGrid[0][0] == 1:
            return 0
        for row in range(m):
            if obstacleGrid[row][0] != 1:
                dp[row][0] = 1
            else:
                break
        for col in range(1, n):
            if obstacleGrid[0][col] != 1:
                dp[0][col] = 1
            else:
                break
        for row in range(1, m):
            for col in range(1, n):
                if obstacleGrid[row][col] != 1:
                    dp[row][col] = dp[row - 1][col] + dp[row][col - 1]
                else:
                    continue
        return dp[m - 1][n - 1]

第五题:最大正方形

Leetcode221. 最大正方形:中等题 (详情点击链接见原题)

在一个由 '0''1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积

1. 确定 dp 数组(dp table)以及下标的含义
dp[i][j] : 多补充一行全 0、多一列全 0dp[i][j] 的含义为以 matrix[i[j] 为右下角的正方形的最大边长

在这里插入图片描述

2. 确定递推公式
dp[r][c] = min(dp[r - 1][c], dp[r][c - 1], dp[r - 1][c - 1]) + 1
翻译成中文为若某格子的值为 1,则以此为右下角的正方形的最大边长为:上面的正方形,左边的正方形,左上的正方形中边长最小的那个,再加上此格

python代码解法

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if not matrix or len(matrix) < 1 or len(matrix[0]) < 1:
            return 0
        row, col = len(matrix), len(matrix[0])
        maxSide = 0
        dp = [[0 for _ in range(col + 1)] for _ in range(row + 1)]
        for r in range(1, row + 1):
            for c in range(1, col + 1):
                if matrix[r - 1][c - 1] == '1':
                    dp[r][c] = min(dp[r - 1][c], dp[r][c - 1], dp[r - 1][c - 1]) + 1
                    maxSide = max(maxSide, dp[r][c])
        return maxSide * maxSide
  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_lover_forever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值