1. 题目描述
2. 解题思路
爬楼梯,该怎么爬呢?那我们先来找找规律,于是我利用excel穷举了一下n=5到n=8的情况
看起来在排列组合上似乎有一点点规律,但仔细看看规律又不太明显,然后只能放弃这种想法。
晚上躺在床上睡觉前突然想到,这只能一步楼梯或者两步楼梯,不就有点像二叉树的两个子节点,利用自身剩余的步数来构建子节点,直到生成叶子节点,那么途经的节点组合就为一种爬楼梯方法,只要能够得出这一棵树的所有叶子节点的个数就能得出总共爬楼梯的方法了,有点抽象?来个图看看就明白了(左节点为走了一级,右节点为走了两级)
当我把这个答案提交后,嗯,n=44时候超时!我突然发现,这个算法的时间复杂度可是2的n次方,怪不得!那既然这样,只能另寻出路了,于是我干脆把前面几种数都打印出来看看有没有什么规律,然后发现
1 2 3 5 8 13 21 34 55
这不就是大名鼎鼎的斐波那契数列吗?他的规律就是
f(n) = f(n-1) + f(n-2)
既然这样就好办了,动态规划算法,一个for
循环就可以搞定了,时间复杂度是O(n)。
然而官解总是有惊喜的,充满数学肌肉的解法,有用了线性代数的相关知识求解,也有用斐波那契数列的通项公式直接计算,时间复杂度可以达到O(log n),fine,还是很值得学习的,有兴趣可以去看看。
3. 代码实现
3.1 递归树(卒 | 时间超限)
public int climbStairs(int n) {
if (n == 0)
return 1;
else if (n < 0)
return 0;
else
return climbStairs(n - 1) + climbStairs(n - 2);
}
3.2 动态规划
public int climbStairs(int n) {
if (n == 1)
return 1;
if (n == 2)
return 2;
int one = 1, two = 2, three = 0;
for (int i = 3; i <= n; i++) {
three = one + two;
one = two;
two = three;
}
return three;
}