LeetCode——Climbing Stairs
# 70
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?
Note: Given n will be a positive integer.
这个问题是给定一个n,通过用不同个数的1或2,相加可以得到n的情况个数。其实就是一个斐波那契的数列问题。一开始我拿到题目,就直接通过正常思路写。我用了递归来解决这个问题。代码非常的简单,但是当输入值太大,递归所用的时间太长,在LeetCode上是通过不了的。
- C++
class Solution{
public:
int climbStairs(int n){
if(n == 1)
return 1;
if(n == 2)
return 2; //当n为2时,有两种方法,两个1或者2
return climbStairs(n - 1) + climbStairs(n - 2);
}
这里的递归思想其实很容易理解。但熟用递归思想去考虑题目还是需要训练的。可以将这个代码进行改写。
- C++解法二
class Solution {
public:
int climbStairs(int n) {
int f1,f2;
f1 = 1;
f2 = 2;
if(n == 1)
return f1;
if(n == 2)
return f2;
int fn;
for(int i = 3;i <= n;i++)
{
fn = f1 + f2;
f1 = f2;
f2 = fn;
}
return fn;
}
};
这样写当然是没问题的,我去找了其他人的答案看了下,用到了动态规划法填表,跟递归其实差不多,使用了一个vector数组,动态性地提高了效率。这两个解法的效率其实差不多。下面的代码看起来更加简洁。
- C++解法三
class Solution {
public:
int climbStairs(int n) {
if (n <= 1)
return 1;
vector<int> f(n+1);
f[0] = 1; f[1] = 1;
for (int i = 2; i <= n; ++i) {
f[i] = f[i - 1] + f[i - 2];
}
return f.back(); //返回最后一个元素
}
};
- C++解法四
只用两个整型变量,进一步优化空间。参考解法二,是对算法二的优化。
class Solution {
public:
int climbStairs(int n) {
int a = 1, b = 1;
while (n--) {
b += a; //b就是解法二中的fn
a = b - a;
}
return a;
}
};
看到另一种解法二的写法,也是动态规划的方法,对空间进行了优化。
- C++解法五
这是对算法三的空间优化。
class Solution {
public:
int climbStairs(int n)
{
vector<int> f(3);
f[0] = 1;
f[1] = 1;
for (int i = 2; i <= n; i++)
{
f[i%3] = f[(i-1)%3] + f[(i-2)%3];
}
return f[n%3];
}
};
写一下对应解法三的Java形式。
- Java
public class Solution {
public int climbStairs(int n) {
if (n <= 1)
return 1;
int[] f = new int[n+1];
f[0] = 1; f[1] = 1;
for (int i = 2; i <= n; i++) {
f[i] = f[i - 1] + f[i - 2];
}
return f[n];
}
}
再写一下Python的形式。
- Python
class Solution:
# @param n, an integer
# @return an integer
def climbStairs(self, n):
f = [1 for i in range(n+1)]
for i in range(2, n+1):
f[i] = f[i-1] + f[i-2]
return f[n]
Python在初始化上简单了一点。其他都差不多。