动态规划基础知识
某个问题有很多重叠子问题,适用动态规划。
贪心算法:局部选最优
动态规划:每一个状态一定是由上一个状态推导出来的。
- 动规5步曲:
- 确定dp数组以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
- 动规debug步骤:
1、打印dp数组,看实际和自己预先推导的哪里不一样
2、若打印结果与预先推导一样,排查递归公式、初始化、遍历顺序。
3、若打印结果与预先推导不同,代码实现细节有问题
思路
1、迭代法
推荐!
- 确定dp数组以及下标的含义
dp[i]:第i个数的斐波那契数值是dp[i] - 确定递推公式
状态转移方程 dp[i] = dp[i - 1] + dp[i - 2]; - dp数组如何初始化
dp[0]=0
dp[1]=1 - 确定遍历顺序
dp[i]依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后. - 举例推导dp数组
当n=6时,dp数组应该是:0 1 1 2 3 5 8
时间复杂度O(n)
空间复杂度O(1)
class Solution:
def fib(self, n: int) -> int:
#F(0)=0,F(1)=1
if n <= 1:
return n
a=0
b=1
for i in range(2,n+1):
res=a+b
a=b
b=res
return b
2、递归法
时间复杂度:O(2^n)
空间复杂度:O(n),算上了递归的栈所占空间
class Solution:
def fib(self, n: int) -> int:
#2、递归法
if n <=1 :
return n
return self.fib(n-1)+self.fib(n-2)