本文主要介绍Fibonacci sequence(斐波那契数列)的相关知识,同时通过示例代码介绍相关问题的解决方法。
Fibonacci sequence, the sequence of numbers 1, 1, 2, 3, 5, 8, 13, 21, …, each of which, after the second, is the sum of the two previous numbers; that is, the nth Fibonacci number F(n) = F(n − 1) + F(n − 2).
The sequence was noted by the medieval Italian mathematician Fibonacci (Leonardo Pisano) in his Liber abaci.
题目描述:
已知有一个Fibonacci sequence,给定n作为数列的位置,求该位置的数值。
此题通常有三种解法,分别为:递归法、数组法(内存法)及平推法(循环法)。
下面分别给出这三种解法的示例代码。
使用递归法解决Fibonacci Number问题的示例代码如下:
class Solution {
public:// calculate the value with recursionint fib(int n) {if (0 == n || 1 == n) {return n;}return fib(n - 1) + fib(n - 2);}
};递归法对应的时间复杂度为:O(2^n),空间复杂度为:O(n)。
使用数组法解决Fibonacci Number问题的示例代码如下:
class Solution {
public:// dynamic programming approachint fib(int n) {if (n < 2) {return n;}int mem[n + 1];mem[0] = 0;mem[1] = 1;for (int i = 2; i <= n; i++) {mem[i] = mem[i - 1] + mem[i - 2];}return mem[n];}
};数组法对应的时间复杂度为:O(n),空间复杂度为:O(n)。
使用平推法解决Fibonacci Number问题的示例代码如下:
class Solution {
public:// with imperative approachint fib(int n) {if (n < 2) {return n;}int prevprev = 0;int prev = 1;int cur = 0;for (int i = 1; i < n; i++) {cur = prevprev + prev;prevprev = prev;prev = cur;}return cur;}
};平推法对应的时间复杂度为:O(n),空间复杂度为:O(1)。
题目描述:
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
分析思路:此题本质上就是Fibonacci sequence问题。对于第n个台阶,之前的情况只有两种可能:在n-1个台阶跨1步上去;或在n-2个台阶跨2步上去(因为根据题干,我们一步只能跨1个或2个台阶,这点至关重要!)。因此,达到第n个台阶的方法数量就满足Fibonacci sequence了:F(n) = F(n - 1) + F(n - 2)。当然,这里n必须要大于2,因为台阶数为0是没有意义的。
有了上述分析思路,就可以参考2.1节Fibonacci Number问题的解法来解答此问题了(但需注意n需大于2)。
这里给出平推法的示例代码:
class Solution {
public:// with imperative approachint climbStairs(int n) {if (n < 3) {return n;}int prevprev = 1;int prev = 2;int cur = 0;for (int i = 2; i < n; i++) {cur = prevprev + prev;prevprev = prev;prev = cur;}return cur;}
};从上述代码可以看到,我们是基于n大于2来计算Fibonacci sequence的数值的,而2.1.3节中的平推法是基于n大于1来计算的。