Question
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?
本题难度Easy。有3种算法分别是: 递归、迭代、数学公式
【思路】
这三种算法的思路都是一样的。设f(n)
表示爬n
阶楼梯的不同方法数,为了爬到第n
阶楼梯有两种方法:
- 从第
n-1
阶爬1步 - 从第
n-2
阶爬2步
因此有f(n)=f(n-1)+f(n-2)
,它是一个斐波那契数列。
由于递归法复杂度高(时间 O(1.618^N) 空间 O(N)
),不推荐使用。
1、迭代法
【复杂度】
时间 O(N) 空间 O(1)
【代码】
public class Solution {
public int climbStairs(int n) {
//require
int prev=0;
int cur=1;
//invariant
for(int i=1;i<=n;i++){
int tmp=cur;
cur+=prev;
prev=tmp;
}
//ensure
return cur;
}
}
2、数学公式法
【复杂度】
时间 O(1) 空间 O(1)
【附】
斐波那契数列的通项公式:
3、其他方法
这道题我开始做是使用了[LeetCode]Unique Paths的思路,将爬1步变换成行i
,爬2步变换成列j
,然后利用DP方法对所有i+j*2==n
的值加到count
中。
public class Solution {
public int climbStairs(int n) {
//require
if(n<2)
return 1;
int rowSize=n+1;
int colSize=n/2+1;
int[][] dp=new int[rowSize][colSize];
for(int i=0;i<rowSize;i++)
dp[i][0]=1;
for(int i=0;i<colSize;i++)
dp[0][i]=1;
int count=0;
//invariant
for(int i=1;i<rowSize;i++)
for(int j=1;j<colSize;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
if(i+j*2==n)
count+=dp[i][j];
}
//ensure
if(n%2==0)
return count+2;
else
return count+1;
}
}
实际上是在求矩阵dp
上某个斜边上所有点的值之和。该方法对于某个点的路径计算是最佳,但是对于本问题来说,比起斐波那契数列来说确实麻烦许多。