题目地址:https://leetcode-cn.com/problems/climbing-stairs/
1 2 3 4 5
| 题目: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意: 给定 n 是一个正整数
|

(动态规划)
分析
1 2 3 4 5
| 1种 1 层 1 2种 2 层 11 2 3种 (2+1) 3 层 111 12 21 5种 (3+2) 4 层 1111 112 121 211 22 8种 (5+3) 5 层 11111 1112 1121 1211 122 2111 212 221
|
不是那么容易的可以得出第n层的计算公式:
f(n) = f(n-1) + f(n-2) 【斐波那契数列】
所以可以通过递归的方式计算出前面的值,又因为该题计算第n层的时候只需要关注n-1 和 n-2 层的值,所以只需要有三个变量即可完成统计。
1 2 3 4 5 6 7 8 9 10 11
| public static int climbStairs(int n) { int step_n_2 = 0,step_n_1 = 0,step_n = 1; for (int i = 1; i <= n; i++) { step_n_2 = step_n_1; step_n_1 = step_n; step_n = step_n_2 + step_n_1; } return step_n; }
|
可以对上面逻辑进行简单的优化
因为上面是定义了三个变量来记录 三个位置的值,我们可以通过一个长度为3的数组存放三个位置的值。
1 2 3 4 5 6 7 8 9 10
| public static int climbStairs(int n) { int arr[] = new int[]{0, 0, 1}; for (int i = 1; i <= n; i++) { arr[0] = arr[1]; arr[1] = arr[2]; arr[2] = arr[0] + arr[1]; } return arr[2]; }
|
解法二(通项公式)
如下内容摘自官网,至于怎么推算,我已流下了没有好好学习的眼泪 =,=

知道具体通向公式的话,代码相对来说就比较简单了,如下:
1 2 3 4 5
| public static int test3(int n){ double sqrt5 = Math.sqrt(5); double temp = Math.pow((1 + sqrt5) / 2, n + 1) - Math.pow((1 - sqrt5) / 2, n + 1); return (int) (temp / sqrt5); }
|
关于上面代码中 n + 1 的说明
1 2
| 因为斐波那契数列为 f(1)=1,f(2)=1,f(3)=2,f(4)=3 而这儿爬楼梯数列为 f(1)=1,f(2)=2,f(3)=3, 差一项,所以要+1
|