You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Example 1:
Input:2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input:3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
一道很经典的题目 爬楼梯 一次可以上一级台阶 也可以上两级 问上n级台阶有多少种方式
设用T(i)表示上i级台阶 有两种方式
1.先上前i-1级 然后上最后一级
2.线上前i-2级 然后上最后两级
所以 T(i) = T(i-1) + T(i-2)
很容易想到递归做法
public class Solution {
public int climbStairs(int n) {
climb_Stairs(0, n);
}
public int climb_Stairs(int i, int n) {
if (i > n) {
return 0;
}
if (i == n) {
return 1;
}
return climb_Stairs(i + 1, n) + climb_Stairs(i + 2, n);
}
}
时间复杂度O(n^2) 会发现这里面有重复计算
我们以T(n)表示爬n层台阶的方式
T(4)=T(3)+T(2)
T(3)=T(2)+T(1)
T(2)会被计算两次 随着台阶数的增多 重复计算会越来越多
所以采取dynamic programming 存储计算结果 避免重复计算
public class Solution {
public int climbStairs(int n) {
if (n == 1) {
return 1;
}
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
没想到dp的基础上还可以优化空间
从表达式T(n) = T(n-1) + T(n-2) 发现和Fibonacci Number的表达式相同 所以可以采取相同办法求解
public class Solution {
public int climbStairs(int n) {
if (n == 1) {
return 1;
}
int first = 1;
int second = 2;
for (int i = 3; i <= n; i++) {
int third = first + second;
first = second;
second = third;
}
return second;
}
}
时间复杂度O(n) 空间复杂度O(1)