【算法积累】动态规划与斐波那契数列
题目
注:本题来自LeetCode题库70.爬楼梯。
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例1:
1 | 输入: 2 |
示例2:
1
2
3
4
5
6 输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
解法1:动态规划法
不难发现,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。
假设我们要爬到第n个台阶,则有两种情况:一是爬到第(n-1)个台阶,然后再往上爬1个台阶即可;二是爬到第(n-2)个台阶,然后再往上爬2个台阶即可。也就是说,爬到第n个台阶的方法数,就是爬到第(n-1)个台阶的方法数与爬到第(n-2)个台阶的方法数之和。
特别地,当n=1时,方法数为1;当n=2时,方法数为2(即1+1或直接爬2个台阶)。
代码实现如下:
1 | // 语言:C |
这种解法的时间复杂度为O(n),空间复杂度为O(n)。
解法2:斐波那契数列法
我们再分析一下解法1,不难发现这其实就是斐波那契数列。所以这道题还可以用斐波那契数列法来解决。下面给出C和Python 3的代码:
1 | // 语言:C |
1 | """ |
同样地,这种解法的时间复杂度为O(n),空间复杂度为O(n)。
解法3:斐波那契公式法
既然知道这道题本质上就是斐波那契数列了,那么我们就可以直接使用公式啦!
斐波那契数列的公式如下:
$$F_n=\frac{1}{\sqrt{5}}\left(\left(\frac{1+\sqrt{5}}{2}\right)^{n+1}-\left(\frac{1-\sqrt{5}}{2}\right)^{n+1}\right)$$
套用这个公式可以很快地解决本题。Python 3代码如下:
1 | """ |
这种方法的时间复杂度为O(log(n))(pow()将会用去log(n)的时间),空间复杂度为O(1)(使用常量级空间)。