509. 斐波那契数

1、题目描述

 2、题目解析

斐波那契数列是典型中的典型题目!

        (来自百度百科)。 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(≥ 2,∈ N*)。

解法一:递归

当时在读书的时候,这道题就是用来专门讲递归算法的题目,简单易懂逻辑。

因为存在以下的递推公式,所以递归代码非常容易

  • F(0) = 0,F(1) = 1
    F(n) = F(n - 1) + F(n - 2),其中 n > 1
class Solution{
    public int fib(int n) {
        if(n==0) return 0;
        if(n==1) return 1;
        return fib(n-1) +fib(n-2);
    }
}

复杂度分析

时间复杂度:O(n^2),递归方法效率是极其低下的,因为会涉及很多重复计算。

空间复杂度:O(n)。

【递归方法效率是极其低下】很多重复计算问题,所以编译后的结果如下,执行用时需要8ms, 仅击败了22.36%的用户:

解法二:动态规划 

使用辅助空间预存每次计算的结果,这样后续每个数据需要获取数据的时候,直接拿之前已经计算好的结果即可,这样效率高很多。

class Solution{
    public int fib(int n) {
        if(n==0) return 0;
        if(n==1) return 1;

        //使用辅助空间,预存结果
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        for(int i = 2; i < n+1; i++){
           dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}

复杂度分析

时间复杂度:O(n),由于每一步骤都已经预存结果,因此时间复杂度就是O(n), for循环的。

空间复杂度:O(n),使用dp辅助空间,预存每次计算的结果。

此次编译效率就高很多,运行结果截图如下:

解法三:继续优化空间

在解决二的基础上,dp辅助空间可以不使用,优化成量模式,这样空间复杂度可以从O(n) 优化到O(1).

class Solution{
    public int fib(int n) {
        if(n==0) return 0;
        if(n==1) return 1;

        //使用变量模式,预存结果
        int one = 0;
        int two = 1;
        int res = one + two;
        for(int i = 2; i < n+1; i++){
           res = one + two;
           one = two;
           two = res;
        }
        return res;
    }
}

复杂度分析

时间复杂度:O(n),由于每一步骤都已经预存结果,因此时间复杂度就是O(n), for循环的。

空间复杂度:O(1),此时用变量模式,预存结果

综上面3种解法,动态规划中,dp[i] = dp[i - 1] + dp[i - 2](递推公式),其实是此类问题中比较难推导的,动态规划问题最困难的就是写出【状态转移方程】。只要能够推断出【状态转移方程】,优化方法无非是用备忘录或者 DP table,再无奥妙可言。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值