Leetcode70–爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
编程语言:python
作者:黑暗主宰
邮箱:shengzhanhe@gmail.com
Leetcode70–爬楼梯
题目描述
原题链接:
https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode/ (中文)
https://leetcode.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode/ (英文)
题目描述:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:
**注意:**给定 n 是一个正整数。
示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 |
---|
示例 2: 输入:3 输出:3 解释: 有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 3. 2 阶 + 1 阶 |
---|
解题思路
博主是一个算法小白,也是通过刷Leetcode来提升自己的编程思维。
对于爬楼梯这道理,第一想到的是排列组合,然后通过一波分析,提交也通过了。然后又参考别人的想法,恍然大悟,原来还可以这样解题。下面就先写递归和动态规划的方法,然后在放出我当时第一次做这个题的code。下文中的图片链接来自于LeetCode官方题解1
方法1:递归
为什么用递归可以做呢,首先逆向思维的分析这道题,如果总共有5个台阶,我们已知登上第4个台阶有 m m m种走法,登上第3个台阶有 n n n种走法,那么登上第5个台阶是不是就有 m + n m+n m+n种走法;有小伙伴说,第4个台阶到第5个台阶是有 m m m种,第3个台阶到第5个台阶不是有 m + 1 m+1 m+1种吗?(那是因为,已知第3个台阶和第4个台阶的走法,从第3个台阶可以走1 阶 + 1 阶,也可以走2 阶,但是走1 阶 + 1 阶这种方法属于第4台阶的方法,所以总体来说是 m + n m+n m+n)。同理,如下图所示,我们只要知道第1阶和第2阶,就能知道第3阶,以此类推。其实说白了,本质上就是一个斐波那契数列,代码如下
def climbStairs(n):
if n == 1:
return 1
if n == 2:
return 2
return climbStairs(n-1) + climbStairs(n-2)
这种方法效率很低,从上图可以看出,随着递归的加深,需要更多的空间去存储数据,并且时间复杂度指数增长。
方法2:动态规划
通过上文的分析可以总结公式
d
p
[
i
]
=
d
p
[
i
−
1
]
+
d
p
[
i
−
2
]
dp\left[ i \right] = dp\left[ {i - 1} \right] + dp\left[ {i - 2} \right]
dp[i]=dp[i−1]+dp[i−2]
更好的理解,如下图所示
对应代码如下:
def climbStairs(n):
res = [0, 1]
for i in range(n):
res[0], res[1]= res[1], res[0] + res[1]
return res[-1]
然后,下面的代码是第一次做这个题时的解法,大佬勿喷
经过一波分析(😜),可以计算2和1的组合计算总共有多少种方法,先计算最多可以有多少个2,然后余下的就是1的数量,然后每次减少一个2,就会增加两个1,组合公式为
c
(
m
,
n
)
=
m
!
n
!
×
[
m
−
n
]
!
c\left( {m,n} \right) = \frac{{m!}}{{n! \times \left[ {m - n} \right]!}}
c(m,n)=n!×[m−n]!m!
然后把每次组合累加,就是总共多少种方法啦。
def climbStairs(self, n):
if n == 1:
return 1
two_nums = n//2
one_nums = n%2
cnt = 0
nums = two_nums + one_nums
while two_nums:
denominator = 1
tmp1 = two_nums
while tmp1:
denominator *= tmp1
tmp1 -= 1
numerator = 1
tmp2= two_nums
tmp3 = nums
while tmp2:
numerator *= tmp3
tmp2 -= 1
tmp3 -= 1
cnt += numerator//denominator
two_nums -= 1
nums += 1
cnt += 1
return cnt
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分析技术问题,我们一起学习进步
注: 文中有写错的地方,欢迎大家不吝指正!!!
https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode ↩︎