70. Climbing Stairs
一、题目
Problem Description:
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?
Example 1:
Input: n = 2
Output: 2
Explanation: There are two ways to climb to the top.
- 1 step + 1 step
- 2 steps
Example 2:
Input: n = 3
Output: 3
Explanation: There are three ways to climb to the top.
- 1 step + 1 step + 1 step
- 1 step + 2 steps
- 2 steps + 1 step
Constraints:
1
<
=
n
<
=
45
1 <= n <= 45
1<=n<=45
二、题解
- 爬楼梯问题是一道经典的DP问题
- 第n个楼梯可以由第n-1楼梯或第n-2个楼梯爬上来
- 其实这道爬楼问题就是经典的斐波那契数列问题:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)
- 由于题目中n>=0,则初始条件给定F(1)=1,F(2)=2
2.1 Approach #1 : Recursion / Brute Force
注:Wrong:Time Limit Exceeded
以下代码由于时间复杂度过高,无法通过
Time complexity :
O
(
2
n
)
O(2^n)
O(2n). Size of recursion tree will be
2
n
2^n
2n.
Recursion tree for n=5 would be like this:
Space complexity : O ( n ) O(n) O(n). The depth of the recursion tree can go upto n n n.
优点:代码简洁明了,可读性高
缺点:如上图二叉树所示,存在大量重复计算
//Recursion / Brute Force
//Time complexity : O(2^n); Space complexity : O(n)
class Solution {
public int climbStairs(int n) {
return F(n);
}
public int F(int n){
if(n == 1) return 1;
if(n == 2) return 2;
return F(n-1) + F(n-2);
}
}
2.2 Approach #2 : Dynamic Programming
空间换时间:dp[]数组用来存储各个F(n)值
Time complexity :
O
(
n
)
O(n)
O(n)
Space complexity :
O
(
n
)
O(n)
O(n)
//Dynamic Programming
//Time complexity : O(n); Space complexity : O(n)
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];
}
}
2.3 Approach #3 : Optimization of Dynamic Programming
无需dp[]数组,只需两个变量保存F(n-1)和F(n-2)值即可
Time complexity :
O
(
n
)
O(n)
O(n)
Space complexity :
O
(
1
)
O(1)
O(1)
//Dynamic Programming
//Time complexity : O(n); Space complexity : O(1)
class Solution {
public int climbStairs(int n) {
if(n == 1) return 1;
int num2 = 1;//num2表示F(n-2);num2初始化为F(1)=1
int num1 = 2;//num1表示F(n-1);num1初始化为F(2)=2
for(int i = 3; i <= n; i++){
int num = num1 + num2;//num表示F(n);F(n)=F(n-2)+F(n-1)
num2 = num1;
num1 = num;
}
return num1;
}
}