problem describing
:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
首先,我只能想到递归求解的方法,即将问题分解成一个个的子问题。
n阶的解=n-1阶的解+n-2阶的解;
可惜他超时了。。。
class Solution {
public:
int climbStairs(int n) {
if(n==0) return 0;
if(n==1) return 1;
if(n==2) return 2;
return climbStairs(n-1)+climbStairs(n-2);
}
};
于是,看了LC上的solution之后,豁然开朗,我们可以把每一步所需要的步数记录在一个数组中,这样就不用产生许多递归的分支,增加内存开销
Dynamic Programming:
class Solution {
public:
int climbStairs(int n) {
int *ans=NULL;
ans =new int[n+1];
if(n==0) return 0;
if(n==1) return 1;
ans[1] =1;
ans[2] =2;
for(int i=3;i<=n;i++)
{
ans[i]=ans[i-1]+ans[i-2];
}
return ans[n];
}
};
时间复杂度取for循环里的基本操作,为O(n),比起第一种递归的O(2^n),减少了许多的时间开销。
减少了时间开销后顺利通过了。
3.斐波那契法
数学上有斐波那契数列,
Fib(n)=Fib(n-1)+Fib(n-2)
其实这与上面的解法类似,只是不需要额外的数组空间来计算
class Solution {
public:
int climbStairs(int n) {
if(n==0) return 0;
int first =1;
int second =2;
for(int i=3;i<=n;i++)
{
int third =first +second;
first =second;
second =first;
}
return third;
}
};