题目地址:https://leetcode.com/problems/climbing-stairs/
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?
题目说一个人要爬楼梯,每次只能爬一阶或者两阶,那么如果给出楼梯的总长度的话,一共有多少种爬法。
我们可以这么考虑问题,当这个人爬楼梯爬最后一步的时候,无非就是两种情况:一种是一阶,一种是两阶。也就是说前面爬楼的方法有两种,一种是climbStairs(n-1),一种是climbStairs(n-2),两种方法加起来就是climbStairs(n-1)+climbStairs(n-2),也就是总共的种类。
写到这里,已经很明白了,这不是斐波那契数列嘛,一个递归不就OK了吗?
public class ClimbingStairs {
public int climbStairs(int n) {
if (n <= 1)
return 1;
if (n == 2)
return 2;
return climbStairs(n - 1) + climbStairs(n - 2);
}
}
要是这么写也行,不过这么写递归次数比较多,比较耗资源,另外如果画出递归树的话,你会发现有很多重复计算,那这就有点浪费了。如果递归不好使,就用迭代,其实迭代的实现也很简单:
public class ClimbingStairs {
public int climbStairs(int n) {
if (n <= 1)
return 1;
if (n == 2)
return 2;
int p = 1;
int q = 2;
int r = 0;
for (int i = 3; i <= n; i++) {
r = p + q;
p = q;
q = r;
System.out.print(r + " ");
}
return r;
}
public static void main(String[] args) {
ClimbingStairs climbingStairs = new ClimbingStairs();
System.out.println(climbingStairs.climbStairs(100));
}
}
时间复杂度为O(n)。
其实这里还有个问题,因为int类型是有范围的,菲波那切数列到了第45项的时候就出现负数了,这个答案明显不符合题意,不过OJ人家认为这个答案是可以的,咱们就不说啥了。如果在实际的应用中,还是需要考虑到这种情况的。