[LeetCode] 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?
Note: Given n will be a positive integer.
Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
这篇博客最开始名字叫做爬梯子问题,总是有童鞋向博主反映移动端打不开这篇博客,博主觉得非常奇怪,自己也试了一下,果然打不开。心想着是不是这个博客本身有问题,于是想再开一个相同的帖子,结果还是打不开,真是见了鬼了。于是博主换了个名字,结果居然打开了?!进经过排查后发现,原来是“爬梯子”这三个字是敏感词,放到标题里面,博客就被屏蔽了,我也真是醉了,完全是躺枪好么,无奈之下,只好改名为爬楼梯问题了 -。-|||。
这个爬梯子问题最开始看的时候没搞懂是让干啥的,后来看了别人的分析后,才知道实际上跟斐波那契数列非常相似,假设梯子有n层,那么如何爬到第n层呢,因为每次只能爬1或2步,那么爬到第n层的方法要么是从第 n-1 层一步上来的,要不就是从 n-2 层2步上来的,所以递推公式非常容易的就得出了:dp[n] = dp[n-1] + dp[n-2]。 由于斐波那契额数列的求解可以用递归,所以博主最先尝试了递归,拿到 OJ 上运行,显示 Time Limit Exceeded,就是说运行时间超了,因为递归计算了很多分支,效率很低,这里需要用动态规划 (Dynamic Programming) 来提高效率,代码如下:
C++ 解法一:
class Solution {
public:
int climbStairs(int n) {
if (n <= ) return ;
vector<int> dp(n);
dp[] = ; dp[] = ;
for (int i = ; i < n; ++i) {
dp[i] = dp[i - ] + dp[i - ];
}
return dp.back();
}
};
Java 解法一:
public class Solution {
public int climbStairs(int n) {
if (n <= 1) return 1;
int[] dp = new int[n];
dp[0] = 1; dp[1] = 2;
for (int i = 2; i < n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n - 1];
}
}
我们可以对空间进行进一步优化,只用两个整型变量a和b来存储过程值,首先将 a+b 的值赋给b,然后a赋值为原来的b,所以应该赋值为 b-a 即可。这样就模拟了上面累加的过程,而不用存储所有的值,参见代码如下:
C++ 解法二:
class Solution {
public:
int climbStairs(int n) {
int a = , b = ;
while (n--) {
b += a;
a = b - a;
}
return a;
}
};
Java 解法二:
public class Solution {
public int climbStairs(int n) {
int a = 1, b = 1;
while (n-- > 0) {
b += a;
a = b - a;
}
return a;
}
}
C++ 解法三:
class Solution {
public:
int climbStairs(int n) {
vector<int> memo(n + );
return helper(n, memo);
}
int helper(int n, vector<int>& memo) {
if (n <= ) return ;
if (memo[n] > ) return memo[n];
return memo[n] = helper(n - , memo) + helper(n - , memo);
}
};
Java 解法三:
public class Solution {
public int climbStairs(int n) {
int[] memo = new int[n + 1];
return helper(n, memo);
}
public int helper(int n, int[] memo) {
if (n <= 1) return 1;
if (memo[n] > 0) return memo[n];
return memo[n] = helper(n - 1, memo) + helper(n - 2, memo);
}
}
C++ 解法四:
class Solution {
public:
int climbStairs(int n) {
if(n <= ) return ;
return climbStairs(n / ) * climbStairs(n - n / ) + climbStairs(n / - ) * climbStairs(n - n / - );
}
};
Java 解法四:
public class Solution {
public int climbStairs(int n) {
if(n <= 1) return 1;
return climbStairs(n / 2) * climbStairs(n - n / 2) + climbStairs(n / 2 - 1) * climbStairs(n - n / 2 - 1);
}
}
最后来看一种叼炸天的方法,其实斐波那契数列是可以求出通项公式的,推理的过程请参见 知乎上的这个贴子,那么有了通项公式后,直接在常数级的时间复杂度范围内就可以求出结果了,参见代码如下:
C++ 解法五:
class Solution {
public:
int climbStairs(int n) {
double root5 = sqrt();
return ( / root5) * (pow(( + root5) / , n + ) - pow(( - root5) / , n + ));
}
};
Java 解法五:
public class Solution {
public int climbStairs(int n) {
double root5 = Math.sqrt(5);
double res = (1 / root5) * (Math.pow((1 + root5) / 2, n + 1) - Math.pow((1 - root5) / 2, n + 1));
return (int)res;
}
}
Github 同步地址:
类似题目:
参考资料:
https://leetcode.com/problems/climbing-stairs/
https://leetcode.com/problems/climbing-stairs/discuss/25345/Easy-solutions-for-suggestions.
https://leetcode.com/problems/climbing-stairs/discuss/25296/3-4-short-lines-in-every-language
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Climbing Stairs 爬梯子问题的更多相关文章
- [LintCode] Climbing Stairs 爬梯子问题
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- [Leetcode] climbing stairs 爬楼梯
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- [LeetCode] 70. Climbing Stairs 爬楼梯问题
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- [LeetCode] Min Cost Climbing Stairs 爬楼梯的最小损失
On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...
- [LeetCode] 746. Min Cost Climbing Stairs 爬楼梯的最小损失
On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...
- [LeetCode] 70. Climbing Stairs 爬楼梯
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- Leetcode: climbing stairs
July 28, 2015 Problem statement: You are climbing a stair case. It takes n steps to reach to the top ...
- [LeetCode] Climbing Stairs (Sequence DP)
Climbing Stairs https://oj.leetcode.com/problems/climbing-stairs/ You are climbing a stair case. It ...
- [leetcode]70. Climbing Stairs爬楼梯
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
随机推荐
- Android之图片加载框架Fresco基本使用(二)
PS:最近看到很多人都开始写年终总结了,时间过得飞快,又到年底了,又老了一岁. 学习内容: 1.进度条 2.缩放 3.ControllerBuilder,ControllerListener,Post ...
- 微信小程序的应用及信息整合,都放到这里了
微信小程序终于开始公测了,这篇文章也终于可以发布了. 这篇文章可以说是微信小程序系列三部曲最后一篇.8 月份,小程序推出前,我写了<别开发 app 了>详细阐述了为什么创业应该放弃原生 a ...
- Java进击C#——语法之多线程
本章简言 上一章中笔者对C#一些独有的语法点进行讲解,相信也可以看C#的一些神奇之处.那么本章主要是放在多线程这方面的知识.不管是C#还是JAVA在开发过程或多或少都会用到关于多线程的编程.当然笔者不 ...
- WCF学习系列汇总
最近在学习WCF,打算把一整个系列的文章都”写“出来,包括理论和实践,这里的“写”是翻译,是国外的大牛写好的,我只是搬运工外加翻译.翻译的不好,大家请指正,谢谢了.如果觉得不错的话,也可以给我点赞,这 ...
- [解决方案]CREATE DATABASE statement not allowed within multi-statement transaction.
CREATE DATABASE statement not allowed within multi-statement transaction. 刚开始报这个错误的时候,我上度娘搜了一下. 别人是在 ...
- 征途 bzoj 4518
征途(1s 256MB)journey [问题描述] Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天 ...
- JAVA基础培训(isoft)
我们
- PHP 原型模式
原型模式:原型模式是先创建好一个原型对象,然后通过拷贝原型对象来创建新的对象.适用于大对象的创建,因为创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可.也可以用作动态 ...
- 第二章作业-第3题(markdown格式)-万世想
第3题题目是: 完成小组的"四则运算"项目的需求文档(使用Markdown写文档),尝试同组成员在各自PC上修改同一文档后,如何使用Git命令完成GitHub上的文档的更新,而不产 ...
- ASP.NET MVC 3 技术(九) 301永久重定向不带www域名到带www的域名
在 .net 4 中实现永久重定向非常容易,可以参考ASP.NET MVC3 技术(四) 永久重定向方法.今天主要说明下怎么在 asp.net mvc 3 实现从带www的域名永久重定向到不带www的 ...