Leetcode - Climbing Stairs
来源:互联网 发布:rt809h编程器 编辑:程序博客网 时间:2024/06/07 03:57
Question
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?
JavaCode
//版本一: 寻找递推公式,使用for循环统计不同的走法public int climbStairs(int n) { if(n < 3) return n; int fun = 0; int fun1 = 2; int fun2 = 1; for(int i = 3; i <= n; ++i) { fun = fun1 + fun2;//递推公式: f(n)=f(n-1)+f(n-2) fun2 = fun1;//循环转移关系: f(n-2) <-- f(n-1) fun1 = fun;//循环转移关系: f(n-1) <-- f(n) } return fun;}//版本二: 寻找递推公式,使用递归统计不同的走法public int climbStairs(int n) { if(n < 3) return n; return climbStairs(n-1) + climbStairs(n-2);}//版本三: 递归构造二叉树,叶子节点的个数即为不同的走法public int climbStairs(int n) { return grow(n, 0);}private int grow(int n, int sum) { //如果剩余2阶以上,继续生长子节点 if(n - 2 > 0) sum = grow(n-2, sum); //如果剩余1阶以上,继续生长子节点 if(n - 1 > 0) sum = grow(n-1, sum); //如果恰好剩余2阶或1阶,则到达叶子节点 if(n < 3) sum++; return sum;}
说明
本题的抽象数学模型非常类似于斐波那契数列,如果n表示总的阶梯数,f(n)表示不同的走法,则有通项公式f(n)=f(n-1)+f(n-2)。这个公式可以这么理解,当走到第n-1阶时,再多走1阶就到了第n阶,所以f(n-1)构成了f(n)的一部分,类似的,当走到第n-2阶时,再一次走2阶(这一步只能这么走,如果分两次走,则会和f(n-1)的情况出现相同的走法),所以f(n-2)构成了f(n)的另一部分,又因为每一步只能走1阶或2阶,所以f(n)只能由这两种走法衍生出来。那么得到f(n)只与前两项相关,从而可以用循环替代递归,分别对应版本一和版本二的解法。
版本三的思路是我最开始想到的方法,因为直观地来理解,除最后一步外每一步都有两种走法,所以可以用二叉树描述爬楼梯的过程。从第1阶开始,每走一步就生长出两个子节点,左子节点表示当前走1阶,右子节点表示当前走2阶,如此递归循环下去,最后一步可能是走1阶也可能是走2阶,当到达楼梯顶端时则得到叶子节点,且每个叶子节点代表一种走法,统计整棵树的叶子节点个数就得到了所有的不同走法。
我们可以分析一下时间复杂度,版本一是O(n),版本二和三都约是O(2^n),由于使用递归会存在大量的重复计算,所以版本二和三的代码在n取较大值时运行会超时。实际上,还有一种时间复杂度为O(logn)的解法,利用了矩阵的幂和分治法的思想,可以参考博文计算斐波纳契数,分析算法复杂度。
- LeetCode: Climbing Stairs
- LeetCode: Climbing Stairs
- [LeetCode]Climbing Stairs
- LeetCode Climbing Stairs
- [Leetcode] Climbing Stairs
- Leetcode: Climbing stairs
- LeetCode Climbing Stairs
- [LeetCode] Climbing Stairs
- leetcode 107: Climbing Stairs
- [LeetCode] Climbing Stairs
- [LeetCode]Climbing Stairs
- [leetcode]Climbing Stairs
- LeetCode-Climbing Stairs
- [leetcode] Climbing Stairs
- LeetCode - Climbing Stairs
- LeetCode:Climbing Stairs
- Leetcode Climbing Stairs
- LeetCode | Climbing Stairs
- 欧几里德与拓展欧几里德算法
- iOS 时间戳转换为时间、NSDate转NSString、NSString转NSDate
- 如何js将数组转化为json数组,然后后台如何解析?
- 51Nod-1046-A^B Mod C
- javascript 开发多种类型的应用(Electron 跨平台开发)
- Leetcode - Climbing Stairs
- linux等待队列wait_queue_head_t和wait_queue_t
- Context单例模式的一枝独秀
- Navicat for MySQL如何备份和还原数据
- Java命名规范
- C++文件读写详解(ofstream,ifstream,fstream)
- 再次深入理解IRP
- IOS开发ARC forbids explicit message send of 'autorelease'错误解决办法
- plsql自动补全