587 字
3 分钟
代码随想录算法训练营第二十九天 | 动态规划 Part02

62. 不同路径#

LeetCode 62. Unique Paths

class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 初始化一个 m 行 n 列的二维数组用于备忘录
self.memo = [[0] * n for _ in range(m)]
return self.dp(m - 1, n - 1)
def dp(self, x, y):
# 起点只有一种走法
if x == 0 and y == 0:
return 1
# 越界情况直接返回 0
if x < 0 or y < 0:
return 0
# 如果备忘录中已有结果,直接返回
if self.memo[x][y] > 0:
return self.memo[x][y]
# 状态转移:从上方或左方走到当前位置
self.memo[x][y] = self.dp(x - 1, y) + self.dp(x, y - 1)
return self.memo[x][y]

63. 不同路径 II#

LeetCode 63. Unique Paths II

class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m, n = len(obstacleGrid), len(obstacleGrid[0])
# 备忘录初始化为 0
self.memo = [[0] * n for _ in range(m)]
return self.dp(m - 1, n - 1, obstacleGrid)
def dp(self, x, y, obstacleGrid):
# 遇到障碍物,无法通行
if obstacleGrid[x][y] == 1:
return 0
# 起点,如果没有障碍,则返回 1
if x == 0 and y == 0:
return 1
# 越界处理
if x < 0 or y < 0:
return 0
# 如果该点已有计算结果,直接返回
if self.memo[x][y] > 0:
return self.memo[x][y]
# 状态转移
self.memo[x][y] = self.dp(x - 1, y, obstacleGrid) + self.dp(x, y - 1, obstacleGrid)
return self.memo[x][y]

343. 整数拆分#

LeetCode 343. Integer Break

class Solution:
def integerBreak(self, n: int) -> int:
# 初始化备忘录
self.memo = [-1] * (n + 1)
return self.dp(n)
def dp(self, n):
# 递归出口:n=0 时无法继续拆分,返回 0
if n == 0:
return 0
if n == 1:
return 1
# 已计算过的直接返回
if self.memo[n] > 0:
return self.memo[n]
res = float('-inf')
# 尝试每一种拆分 i + (n - i),选择最大乘积
for i in range(1, n):
# 两种情况:继续拆分(n-i) or 不拆(n-i)
res = max(res, i * max(self.dp(n - i), n - i))
self.memo[n] = res
return res

96. 不同的二叉搜索树#

LeetCode 96. Unique Binary Search Trees

class Solution:
def numTrees(self, n: int) -> int:
# 初始化一个二维备忘录 memo[l][r]
self.memo = [[0] * (n + 1) for _ in range(n + 1)]
return self.dp(1, n)
def dp(self, l, r):
# 空区间或单节点都只有一种 BST 结构
if l >= r:
return 1
# 已有结果,直接返回
if self.memo[l][r] != 0:
return self.memo[l][r]
res = 0
# 枚举所有可能的根节点 i
for i in range(l, r + 1):
# 左子树为 [l, i-1],右子树为 [i+1, r]
left = self.dp(l, i - 1)
right = self.dp(i + 1, r)
# 左右子树组合数相乘
res += left * right
self.memo[l][r] = res
return res
代码随想录算法训练营第二十九天 | 动态规划 Part02
https://fuwari.vercel.app/posts/code_musings_day_twenty-nine/
作者
Jarrett
发布于
2025-07-14
许可协议
CC BY-NC-SA 4.0