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

(动态规划)
分析
| 12
 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 层的值,所以只需要有三个变量即可完成统计。
| 12
 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的数组存放三个位置的值。
| 12
 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];
 }
 
 | 
解法二(通项公式)
如下内容摘自官网,至于怎么推算,我已流下了没有好好学习的眼泪 =,=

知道具体通向公式的话,代码相对来说就比较简单了,如下:
| 12
 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 的说明
| 12
 
 | 因为斐波那契数列为 f(1)=1,f(2)=1,f(3)=2,f(4)=3而这儿爬楼梯数列为 f(1)=1,f(2)=2,f(3)=3, 差一项,所以要+1
 
 |