力扣509斐波那契数用动态规划解决

题目要求

动规五部曲:
这⾥我们要⽤⼀个⼀维 dp 数组来保存递归的结果。
1. 确定 dp 数组以及下标的含义
        dp[i]的定义为:第 i 个数的斐波那契数值是 dp[i]。
2. 确定递推公式
        为什么这是⼀道⾮常简单的⼊⻔题⽬呢?
因为题⽬已经把递推公式直接给我们了:状态转移⽅程 dp[i] = dp[i - 1] + dp[i - 2];
3. dp 数组如何初始化
题⽬中把如何初始化也直接给我们了,如下:
        dp[0]=0;
        dp[1]=1;
4. 确定遍历顺序
        从递归公式dp[i] = dp[i - 1] + dp[i - 2]; 中可以看出, dp[i] 是依赖 dp[i - 1] dp[i - 2] ,那么遍历的顺序⼀定是从前到后遍历的。
5. 举例推导 dp 数组
        按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2] ,我们来推导⼀下,当 N 10 的时候, dp 数组应该是如下的数列:
        0 1 1 2 3 5 8 13 21 34 55
如果代码写出来,发现结果不对,就把 dp 数组打印出来看看和我们推导的数列是不是⼀致的。
以上我们⽤动规的⽅法分析完了, C 代码如下:
int fib(int n){
	int dp[n+1];
	if(n<=1)
        return n;
	else
	{
		dp[0]=0;
		dp[1]=1;
		for(int i=2;i<=n;i++)
			dp[i]=dp[i-1]+dp[i-2];
        return dp[n];
	}
}
C++ 代码如下:
class Solution {
public:
    int fib(int N) {
        if (N <= 1) return N;
        vector<int> dp(N + 1);
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= N; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
         }
           return dp[N];
     }
};

当然可以发现,我们只需要维护两个数值就可以了,不需要记录整个序列,所以for循环中的内容可以改成如下所示:

for (int i = 2; i <= N; i++) {
    int sum = dp[0] + dp[1];
    dp[0] = dp[1];
    dp[1] = sum;
 }

改过之后时间复杂度不变依旧是O(n),而空间复杂度由原来的O(n)转变为O(1)。

提交结果显示正确。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值