您的位置:首页 > 其它

LeetCode每日一题--爬楼梯

2020-03-15 18:21 302 查看

  【前言】坚持日更LeetCode刷题系列

    不积跬步,无以至千里;不积小流,无以成江海。愿与诸君共勉!


  【题目】70.爬楼梯

    题目描述:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

    每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

    

注意:
给定 n 是一个正整数。


    示例:

示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶

示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

    【概论】:是不是有部分朋友觉得这题十分熟悉??接下来,我将从不同的角度来打开这题的新视野(部分思路参考自LeeCode官方以及评论区前辈)。

    

思路一:
利用递归的思想,每次都将爬1阶或2阶的情况进行组合。在每一次的模拟中,我们都调用函数来进行,并返回爬1阶和2阶楼梯函数的值之和。具体代码如下:

def climb(i,n):
if(i>n):
return 0
elif(i==n):
return 1
else:
return climb(i+1,n) + climb(i+2,n)

class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
return climb(0,n)

    没看懂?没关系,下面给出n=5时的结构图你就懂了。

    图片来源于LeeCode。

    很显然其中进行了很多重复的调用,这种解法显然是不优的。

    运行结果:提交未通过,出现了

超时
错误。


    

思路二:
有了前面的理解,那么我们很清晰的意识到第i次的方法数与第i-1次和第i-2次有关,因为每次都只能爬1或2阶,因此当在第i个台阶时,它的起点只能为i-1或i-2阶,因此其满足climb[i] = climb[i-1]+climb[i-2]的关系。具体代码如下:

class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
map1 = {}  #思考下用字典做存储的好处
map1[1] = 1
map1[2] = 2
for i in range(3,n+1):
map1[i] = map1[i-1] + map1[i-2]
return map1[n]

    运行结果:
    

    关于其中一些知识的链接:

    动态规划图解(漫画版)


    

思路三:
在上一个思路中,我给出了climb[i]=climb[i-1]+climb[i-2]的表达式,是不是有朋友已经想到了斐波拉契数列,或者在此之前就已经想到了这种解法,那么它和动态规划又有什么不同呢?其具体代码如下:

class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n<=2:
return n
else:
first = 1
second = 2
for i in range(3,n+1):
third = first + second
first = second
second = third
return second

    运行结果:
    

    当我们用first、second、third三个变量代替原有的存储结构时,空间复杂度显然降低了,但它和动态规划在时间复杂度上相等。


    

思路四:
官方还给出了第一种思路的改进解法–记忆递归;还给出了
斐波拉契公式,Binets 方法数学解题思路,有兴趣的朋友可以通过下方链接自行了解。

    关于其中一些知识的链接:
    官方题解


    分享就到这里了,欢迎大家一起交流讨论。


    

注明

    题目来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/climbing-stairs/

  • 点赞 2
  • 收藏
  • 分享
  • 文章举报
Mingw_ 发布了36 篇原创文章 · 获赞 64 · 访问量 2775 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: