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
,那么下一步可以移动到下一行的下标i
或i + 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] = 1for col in range(1, n):dp[0][col] = 1for 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 0for row in range(m):if obstacleGrid[row][0] != 1:dp[row][0] = 1else:breakfor col in range(1, n):if obstacleGrid[0][col] != 1:dp[0][col] = 1else:breakfor 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:continuereturn dp[m - 1][n - 1]
第五题
Leetcode221. 最大正方形:中等题 (详情点击链接见原题)
在一个由
'0'
和'1'
组成的二维矩阵内,找到只包含'1'
的最大正方形,并返回其面积
1. 确定 dp
数组(dp table
)以及下标的含义
dp[i][j]
: 多补充一行全 0
、多一列全 0
后 dp[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 0row, col = len(matrix), len(matrix[0])maxSide = 0dp = [[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]) + 1maxSide = max(maxSide, dp[r][c])return maxSide * maxSide