Leetcode70--爬楼梯

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[i1]+dp[i2]
更好的理解,如下图所示在这里插入图片描述

对应代码如下:

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!×[mn]!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

欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分析技术问题,我们一起学习进步
在这里插入图片描述

注: 文中有写错的地方,欢迎大家不吝指正!!!


  1. https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值