原题:
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?
第一次用迭代方法写的代码:(注意:时间超时,不能通过)(自顶向下递归求解)class Solution {
public:
int climbStairs(int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(n == 0){
return 1;
}
if(n == 1){
return 1;
}
else if(n >= 2){
return climbStairs(n-1)+climbStairs(n-2);
}
}
};
以上时间超时,改进方法就是常用的记录中间值,以前常用一个全局变量数组,元素初始化为-1,然后使用递归方法的每次使用climbStairs(n)之前先判断是否为-1,是的话则递归调用,否则就是已经求出值,直接使用即可。这里因为网站上的限制,不能添加全局变量,因此不能用递归的方法,而是使用循环的方式,代码如下:
同上,也是自顶而下,只是记录了中间值,避免了重复计算;
class Solution {
public:
int climbStairs(int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(n <= 0){
return 0;
}
if(n == 1){
return 1;
}
if(n == 2){
return 2;
}
vector<int> midResult(n,0);
midResult[0] = 1;
midResult[1] = 2;
for(int i=2 ; i<n ; i++){
midResult[i] = midResult[i-1]+midResult[i-2];
}
return midResult[n-1];
}
};
考虑到每次只用到前两个数值,以上代码可以进一步优化,优化后的代码如下:(自下而上,从n=1,2...一直到n)
class Solution {
public:
int climbStairs(int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(n <= 0){
return 0;
}
int result = 1,prior = 1;
for(int i=2 ; i<=n ; i++){
int temp = result;
result = result + prior;
prior = temp;
}
return result;
}
};
总结:这个题本身不难,第一步要么走两步,要么走一步,即f(n) = f(n-1) + f(n-2) 。f(1) = 1,f(2) = 2,其实就是斐波那契数列。求解思路也就很简单了。
ps.第一次写的代码不够标准,可读性差,下面稍微好一些:(没必要,还不如第一个代码)
class Solution {
public:
int climbStairs(int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if(n <= 0){
return 0;
}
if(n == 1){
return 1;
}
if(n == 2){
return 2;
}
else if(n > 2){
return climbStairs(n-1)+climbStairs(n-2);
}
}
};