题目描述:
假设你正在爬楼梯,需要n阶才能到达楼顶。每次可以爬1或2阶,你有多少种不同的方法可以爬到楼顶呢?其中n是一个正整数。
思路和算法:
利用动态规划,用f(x)表示爬到第x级台阶的方案数,考虑到最后一步可能跨越了一级台阶,也可能跨越了两级台阶,所以我们可以列出如下式子:f(x) = f(x-1)+f(x-2)。它意味着爬到第x-1级台阶的方案数和爬到第x-2级台阶的方案数的和。这里要统计方案总数,我们就需要对这两项的贡献求和。
以上就是动态规划的转移方程,下面来确定边界条件,我们是从第0级开始爬的,所以第0级爬到第0级我们可以看作只有一种方案,即f(0) = 1;从第0级到第一级也只有一种方案,即爬一级,f(1) = 1。这两个作为边界条件就可以继续向后推导出第n级的正确结果。
算法java实现:
public int climbStairs(int n) {
if (n==0||n==1){
return 1;
}else{
return climbStairs(n-1)+climbStairs(n-2);
}
}
算法优化:
由于这里的f(x)只和f(x-1)与f(x-2)有关,所以我们可以用滚动数组思想把空间复杂度优化成O(1)。
优化后的java实现:
public int climbStairs(int n){
int p=0,q=0,r=1;
for(int i=1;<=n;i++){
p = q;
q = r;
r = p + q;
}
return r;
}
复杂度分析:
- 时间复杂度:循环执行n次,每次花费常数的时间代价,故时间复杂度为O(n)。
- 空间复杂度:只用了常数个变量作为辅助空间,故渐进空间复杂度为O(1)。