[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 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] 70. Climbing Stairs 爬楼梯问题的更多相关文章
- [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 70. Climbing Stairs爬楼梯 (C++)
题目: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either cl ...
- [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 70. Climbing Stairs 爬楼梯 (递归,记忆化,动态规划)
题目描述 要爬N阶楼梯,每次你可以走一阶或者两阶,问到N阶有多少种走法 测试样例 Input: 2 Output: 2 Explanation: 到第二阶有2种走法 1. 1 步 + 1 步 2. 2 ...
- 70. Climbing Stairs爬楼梯
网址:https://leetcode.com/problems/climbing-stairs/ 其实就是斐波那契数列,没什么好说的. 注意使用3个变量,而不是数组,可以节约空间. class So ...
- Leetcode#70. Climbing Stairs(爬楼梯)
题目描述 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 解 ...
- 42. leetcode 70. Climbing Stairs
70. Climbing Stairs You are climbing a stair case. It takes n steps to reach to the top. Each time y ...
- LN : leetcode 70 Climbing Stairs
lc 70 Climbing Stairs 70 Climbing Stairs You are climbing a stair case. It takes n steps to reach to ...
- leetCode 70.Climbing Stairs (爬楼梯) 解题思路和方法
Climbing Stairs You are climbing a stair case. It takes n steps to reach to the top. Each time you ...
随机推荐
- Unity Shader 屏幕后效果——摄像机运动模糊(速度映射图实现)
速度映射图主要是为了得到每个像素相对于前一帧的运动矢量,其中一种方法是使用摄像机的深度纹理来推导. 推导过程如下: 先由深度纹理逆推出NDC(归一化的设备坐标)下的顶点坐标,利用VP矩阵(视角*投影矩 ...
- redis集群之Sentinel
目前我们讲的 Redis 还只是主从方案,最终一致性.读者们可思考过,如果主节点凌晨3 点突发宕机怎么办?就坐等运维从床上爬起来,然后手工进行从主切换,再通知所有的程序把地址统统改一遍重新上线么?毫无 ...
- EF Core 根据已有的数据库来生成 EF 领域模型
1. 如图: 2. 命令 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrame ...
- Python 学习 第17篇:从SQL Server数据库读写数据
在Python语言中,从SQL Server数据库读写数据,通常情况下,都是使用sqlalchemy 包和 pymssql 包的组合,这是因为大多数数据处理程序都需要用到DataFrame对象,它内置 ...
- Disruptor系列(一)— disruptor介绍
本文翻译自Disruptor在github上的wiki文章Introduction,原文可以看这里. 一.前言 作为程序猿大多数都有对技术的执着,想在这个方面有所提升.对于优秀的事物保持积极学习的心态 ...
- Python-绘制3D柱形图
Python-绘制3D柱形图 本文主要讲解如何使用python绘制三维的柱形图,可以得到图1所示的效果. 图1 源代码如下: import numpy as np import matplotlib. ...
- 配置IIS网站可以下载.apk/.ipa文件
添加 扩展名是:.apk MIMI类型是:application/vnd.android.package-archive 扩展名是:.ipa MIMI类型是:application/iphone
- Delphi - 操作Excel数据公式的实现
procedure TF_SMP_FT_NEW.RzBitBtn_StartToChangeClick(Sender: TObject); var i, j, ni, nj, iRows, iCol, ...
- django中视图函数中装饰器
方法一 给指定方法加 from django.utils.decorators import method_decorator class xx(View): @method_decorator(装饰 ...
- Flask笔记:session
session与cookie: cookie是一项浏览器的技术,而不是服务器的技术,服务器端是无法直接操作cookie的,只能通过返回Response响应告诉浏览器怎么操作cookie.而sessio ...