一、题目

剑指Offer面试题10:斐波那契数列_ci

示例:

输入:4
返回值:3
说明:
根据斐波那契数列的定义可知,fib(1)=1,fib(2)=1,fib(3)=fib(3-1)+fib(3-2)=2,fib(4)=fib(4-1)+fib(4-2)=3,所以答案为3。

二、题解

2.1解法一:迭代相加

知识点:动态规划

动态规划算法的基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果。

思路:

斐波那契数列初始化第1项与第2项都是1,则根据公式第0项为0,可以按照斐波那契公式累加到第剑指Offer面试题10:斐波那契数列_ci_02项。

具体做法:

  • step 1:低于2项的数列,直接返回n。
  • step 2:初始化第0项,与第1项分别为0,1.
  • step 3:从第2项开始,逐渐按照公式累加,并更新相加数始终为下一项的前两项。

Java实现代码:

public class Solution {
    public int Fibonacci(int n) {
        //从0开始,第0项是0,第一项是1
        if(n <= 1)    
             return n;
         int res = 0;
         int a = 0;
         int b = 1;
         //因n=2时也为1,初始化的时候把a=0,b=1
         for (int i = 2; i <= n; i++){
         //第三项开始是前两项的和,然后保留最新的两项,更新数据相加
             res = (a + b);
             a = b;
             b = res;
         }
        return res;
    }
}

解法二:递归法

知识点:递归

递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。

思路:

我们也可以根据公式倒推:

  • 终止条件: 当递归到数列第1项或是第0项的时候,可以直接返回数字。
  • 返回值: 返回这一级子问题的数列值。
  • 本级任务: 获取本级数列值:即前两项相加。

具体做法:

  • step 1:低于2项的数列,直接返回n。
  • step 2:对于当前n,递归调用函数计算两个子问题相加。

Java实现代码:

public class Solution {
    public int Fibonacci(int n) {
        //从0开始,第0项是0,第一项是1
        if (n <= 1)    
             return n;
        else{
            //根据公式递归调用函数
            return Fibonacci(n - 1) + Fibonacci(n - 2); 
        }
    }
}