剑指offer面试题10(java版):斐波那契数列

welcome to my blog

剑指offer面试题10(java版):斐波那契数列

题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39

第三次做; 弄清楚 1)递归做法的递归逻辑中哪一部分是当前条件, 哪一部分是新条件新递归 2)将递归改成动态规划, 并通过递推关系发现可以进行状态压缩

public class Solution {
    //递归函数逻辑: 求斐波那契数列的第n项, 斐波那契数列的第n项(当前条件)等于第n-1项(新条件新递归)加第n-2项(新条件新递归)
    public int Fibonacci(int n) {
        if(n<=1)
            return n;
        //return Fibonacci(n-1) + Fibonacci(n-2);
        //通过递归函数可以看出, 斐波那契数列的第n项只依赖于前两项, 所以可以进行状态压缩, 可以自底向上地求第n项, 时间复杂度O(N), 空间复杂度O(1)
        int a = 0, b = 1, res=-1;
        for(int i=2; i<=n; i++){
            res = a + b;
            //update 
            a = b;
            b = res;
        }
        return res;
    }
}

思路

  • 递归求解会存在大量重复
  • 使用循环求解, 注意找准当前项的前两项, 对应到代码中是fibMinus1, fibMinus2

复杂度

第二次 空间复杂度O(1), 要注意for循环边界条件; 初始化→(执行→更新)^n

  • 注意变量的更新
  • 注意for循环边界
  • for循环的执行流程: 初始化a,b → f(a,b) → 更新a,b → f(a,b) → 更新a,b → f(a,b) → 更新a,b → f(a,b) → 更新a,b → f(a,b) →…
public class Solution {
    public int Fibonacci(int n) {
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        int a=0, b=1, res=0;
        for(int i=2; i<=n; i++){
            res = a + b;
            a = b;
            b = res;
        }
        return res;
    }
}

第二次 空间复杂度O(N)

public class Solution {
    public int Fibonacci(int n) {
        //DP版本 f(n) = f(n-1) + f(n-2);
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        int[] arr = new int[n+1];
        arr[0] = 0;
        arr[1] = 1;
        for(int i=2; i<=n; i++)
            arr[i] = arr[i-1] + arr[i-2];
        return arr[n];
    }
}

第二次 复杂的递归

//0,1,1,2,3,5,8,13...
//0,1,2,3,4,5,6,7,...
public class Solution {
    public int Fibonacci(int n) {
        return n == 0 ? 0 : (n == 1 ? 1 : Fibonacci(n-2)) + Fibonacci(n-1);
    }
}
public class Solution {
    public int Fibonacci(int n) {
        // 健壮性判断
        if(n < 0)
            return -1;
        // 正式执行
        int[] result = {0,1};
        if(n<2)
            return result[n];
        int fibResult=0;
        int fibMinus1=1;
        int fibMinus2=0;
        for(int i=2; i<=n; i++){
            fibResult = fibMinus1 + fibMinus2;
            fibMinus2 = fibMinus1;
            fibMinus1 = fibResult;
        }
        return fibResult;
    }
}

/*
// 递归解法
public class Solution{
    public int Fibonacci(int n){
        return n<0? 0: n + Fibonacci(n-1);
    }
}

*/

你可能感兴趣的:(剑指offer,剑指offer)