1.509. 斐波那契数
python
class Solution:
def fib(self, n: int) -> int:
if n < 2:
return n
dp = [0]*(n+1)
dp[0],dp[1] = 0, 1
for i in range(2, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
优化 :只和前两个状态有关,所以可以空间优化,不用存全部状态,只存储前两个状态pre1,pre2,这里不写了
2.20爬楼梯
python
class Solution:
def climbStairs(self, n: int) -> int:
if n < 2:
return n
dp = [0]*(n+1)
dp[1], dp[2] = 1, 2
for i in range(3, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
和上一道题一样,就是起始值不同
3.746. 使用最小花费爬楼梯
注意dp[0],dp[1]初始化为0,一开始就在0或1阶台阶上,不需要花费
python
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
dp = [0]*(n+1)#爬到台阶i的最低花费
for i in range(2, n+1):
dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
return dp[n]
4.62. 不同路径
之前有写过压缩dp二维压缩一维dp
- 二维or一维:只与上面和左边状态有关,压缩成一维dp,原地更新即可
- 初始化,1,0,0,0...,0,反正第一行第一列应该都是1
python
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [0] * n
dp[0] = 1
for i in range(m):
for j in range(1,n):
dp[j] = dp[j] + dp[j-1]
return dp[n-1]
5.63. 不同路径 II
我写的代码是对的也通过了测试,db说我的代码错误(如下)。。

python
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m, n = len(obstacleGrid), len(obstacleGrid[0])
dp = [0] * n
dp[0] = 1
for i in range(m):
for j in range(n):
if obstacleGrid[i][j] == 1:
dp[j] = 0
elif j>0 and obstacleGrid[i][j] != 1:
dp[j] = dp[j-1] + dp[j]
return dp[n-1]
6.343. 整数拆分
- 至少拆成两个正整数,所以dp[0],dp[1]初始化为0
- 重点理解:dp[i] = max(dp[i-j] * j, (i-j) * j, dp[i])
- j是遍历每种拆分
- dp[i]要么是dp[i-j] *j,要么是i-j本身*j(因为dp[i]存储的是i-j拆分的最大乘积,所以要加上i-j本身)
- 遍历每种拆分取最大乘积,所以max里面要加上dp[i]
python
class Solution:
def integerBreak(self, n: int) -> int:
dp = [0] *(n+1)
for i in range(2, n+1):
for j in range(1, i):
dp[i] = max(dp[i-j] * j, (i-j) * j, dp[i])
return dp[n]
7.96. 不同的二叉搜索树
遍历每个值,以每个值为根节点,总的种类等于左子树种类*右子树种类求和
python
class Solution:
def numTrees(self, n: int) -> int:
dp = [0] * (n+1)
dp[0], dp[1] = 1, 1
for i in range(2, n+1):
for j in range(1, i+1):
dp[i] += dp[i-j] * dp[j-1]
return dp[n]