【LeetCode】【简单】【4】70. 爬楼梯

news2024/10/6 6:42:39

题目

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
在这里插入图片描述

动态规划

参考链接:动态规划详解

简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。

一般这些子问题很相似,可以通过函数关系式递推出来。然后,动态规划就致力于解决每个子问题一次,减少重复计算。比如斐波那契数列就可以看做入门级的经典动态规划问题。

核心思想:就在于拆分子问题,记住过往,减少重复计算。

思路

一般看到题目不需要列出来具体的多少种方案,只需要计算有多少种方案,基本上就可以尝试用动态规划算法来解决问题。想好用动态规划就想想动态规划五步曲。

关键词:有多少种方案 算法

  1. 确定dp数组以及下标的含义:定义dp[i]为爬上第 i 级台阶有多少种方案,爬到第i层楼梯,有dp[i]种方法;
  2. 确定状态转移方程:因为每次只可以爬1个或者2个台阶,所以,爬上当前台阶的方案应该是前面两个状态的方案的和,即,dp[i] = dp[i-1] + dp[i-2]
  3. 初始化状态 :从i = 0 级开始爬的,所以从第 0 级爬到第 0 级,我们可以看作只有一种方案,即 dp[0]=1i = 1代表从第 0 级到第 1 级,也只有一种方案,即爬1级,dp[1] = 1i=2代表从第0级到第2级,有两种方案:dp[2]=2
  4. 遍历顺序 :由状态转移方程可知,dp[i]是从dp[i−1]dp[i−2]转移过来,所以从1往100遍历。
  5. 返回值 :一共计算 n 阶楼梯有多少方案,所以返回dp[n]

斐波那契数列:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
用递归来做:f(x)=f(x-1)+f(x-2)
爬第1级台阶:1种方法 1 => f(1)=1
爬第2级台阶:2种方法 1+1 ; 2 => f(2)=2
爬第3级台阶:3种方法 1+1+1;1+2;2+1 => f(3)=3
爬第4级台阶:5种方法 1+1+1+1;1+2+1;1+1+2;2+1+1;2+2 => f(4)=5
……
爬第n级台阶:是第n-1级台阶的方案和+第n-2级台阶的方案和 => f(n)=f(n-1)+f(n-2)

# 暴力递归
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp=[0 for i in range(46)] #  初始化数组为[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        dp[1]=1
        dp[2]=2
        if (n<=1):return n 
        
        for i in range(3,n+1):
            dp[i]=dp[i-1]+dp[i-2]

        return dp[n]

递归树如下:
在这里插入图片描述

递归时间复杂度 = 解决一个子问题时间 * 子问题个数

  • 一个子问题时间 = f(n-1)+f(n-2),也就是一个加法的操作,所以时间复杂度是 O(1);
  • 问题个数 = 递归树节点的总数,递归树的总节点是 2 n − 1 2^n-1 2n1,所以时间复杂度是 O ( 2 n ) O(2^n) O(2n)

所以,递归解法的时间复杂度 : O ( 1 ) ∗ O ( 2 n ) = O ( 2 n ) O(1) * O(2^n) = O(2^n) O(1)O(2n)=O(2n),指数级别的爆炸增长,如果n比较大的话,容易超时。

仔细观察这颗递归树,会发现存在大量重复计算,比如f(8)被计算了两次,f(7)被重复计算了3次…所以这个递归算法低效的原因,就是存在大量的重复计算!

既然存在大量重复计算,那么我们可以先把计算好的答案存下来,即造一个备忘录,等到下次需要的话,先去备忘录查一下,如果有,就直接取就好了,备忘录没有才开始计算,就可以省去重新重复计算的耗时啦!这就是带备忘录的解法。

带备忘录的递归解法(自顶向下)

一般使用一个数组或者一个哈希map充当这个备忘录。保存f(9)~f(1)


其实,还可以用动态规划解决这道题。

自底向上的动态规划

动态规划跟带备忘录的递归解法基本思想是一致的,都是减少重复计算,时间复杂度也都是差不多。但是呢:

  • 带备忘录的递归,是从f(10)往f(1)方向延伸求解的,所以也称为自顶向下的解法。
  • 动态规划从较小问题的解,由交叠性质,逐步决策出较大问题的解,它是从f(1)往f(10)方向,往上推求解,所以称为自底向上的解法。

动态规划有几个典型特征:最优子结构、状态转移方程、边界、重叠子问题。在青蛙跳阶问题中:

  • f(n-1)f(n-2) 称为 f(n) 的最优子结构
  • f(n)= f(n-1)+f(n-2)就称为状态转移方程
  • f(1) = 1f(2) = 2就是边界
  • 比如 f(10)= f(9)+f(8), f(9) = f(8) + f(7) ,这里的f(8)就是重叠子问题。

可以发现,f(n)只依赖前面两个数,所以只需要两个变量a和b来存储,就可以满足需求了,因此空间复杂度是O(1);循环n次,时间复杂度O(n)

我们来看下自底向上的解法,从f(1)往f(10)方向,想想是不是直接一个for循环就可以解决啦,如下:

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        p=1  # f(1)
        q=2  # f(2)

        if (n<3):return n 
        else:
            for i in range(3,n+1):
                r = p+q
                p = q
                q = r
            return r

做动态规划的思路:

  1. 穷举分析 :f(1) ~ f(5)
  2. 确定边界:f(1)和f(2)
  3. 找出规律,确定最优子结构:
    n>=3时,已经呈现出规律 f(n) = f(n-1) + f(n-2) ,因此,f(n-1)和f(n-2) 称为 f(n) 的最优子结构。

    什么是最优子结构?
    一道动态规划问题,其实就是一个递推问题。假设当前决策结果是f(n),则最优子结构就是要让 f(n-k) 最优,最优子结构性质就是能让转移到n的状态是最优的,并且与后面的决策没有关系,即让后面的决策安心地使用前面的局部最优解的一种性质

  4. 写出状态转移方程:f(n)=f(n-1)+f(n-2)
  5. 代码实现:注意从底往上遍历

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贯叶连翘及其天然产物的介绍

贯叶连翘 (Hyperlcurn perforatum L.) 为藤黄科 (Guttiferae) 植物&#xff0c;又名贯叶金丝桃&#xff0c;赶山鞭&#xff0c;小对叶草、千层楼等。迄今为止&#xff0c;已有众多的活性化合物从贯叶连翘中被分离出来。贯叶连翘中不同的成分具有多重药理活性&#xff0c;如其中…

数据结构题目收录(十八)

1、若某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素&#xff0c;则采用____存储方式最节省运算时间。 A&#xff1a;单链表B&#xff1a;仅有头指针的单循环链表C&#xff1a;双链表D&#xff1a;仅有尾指针的单循环链表 解析 选项A、单链表插入…

Java_Map

字典(Map) 概述 HashMap 定义方法 public static void main(String[] args) {// HashMap<Integer, String> Map new HashMap<Integer, String>(); // 定义方法一Map<Integer, String> map new HashMap<Integer, String>(); // 定义方法二// map没…

(续)SSM整合之springmvc笔记(域对象共享数据)(P136-138)

目录 一 使用ServletAPI向request域对象共享数据 二 使用ModelAndView向request域对象共享数据 1 新建TestScopeController 2 index.html 3 书写TestScopeController 4 success.html 5 测试 三 使用Model向request域对象共享数据 1 index.html 2 TestSc…

HTNL---表格标签和列表标签

一、表格标签 对于表格我想就不用做很多细说了吧&#xff0c;Excel大家应该都知道。HTML中的表格不是用来布局页面的而是用来展示数据的。 1&#xff1a;表格标签基本使用 <table> <tr><th>姓名</th> <th>年龄</th> <td>第一</…

【Note5】macvlan,spi,rsyslog,sol

文章目录1.BMC虚拟多网口&#xff1a;macvlan是kernel提供的一种网卡虚拟化技术&#xff0c;可将网卡&#xff08;不一定是真实的物理网卡&#xff09;虚拟出多个接口&#xff0c;这网卡称为master或父接口&#xff0c;这些虚拟接口和外面环境通信都是通过父接口1.1 bridge&…

RESTful 接口设计拓展,接口设计注意事项,注解的简化

文章目录RESTful 接口设计拓展1.多参数传递2.URL拓展3.RESTful接口注意事项4.注解的简化RESTful 接口设计拓展 1.多参数传递 /*** 获取某一个员工&#xff0c;多参数* 1. 请求路径--确认资源--员工--/employees* 2. 请求方法--get* 3. 请求参数--id&#xff0c;name,age* 4. …

Python接口测试之requests详介与实战

目录 requests介绍 1、简述发展史 2、安装 3、官方自评 4、requests支持的请求类型 4、requests的参数与返回 requests接口请求Python脚本实战 1、GET接口实战 2、POST接口实战 3、PUT接口实战 4、DELETE接口实战 requests介绍 Http网络接口请求库 1、简述发展史 …

设计师找灵感就上这几个网站。

推荐5个设计师必备的设计灵感网站&#xff0c;希望对你有帮助&#xff01; 1、pinterest&#xff08;梯子&#xff09; https://www.pinterest.es/Pinterest是以瀑布流的方式来展示图片&#xff0c;在算法上也会根据你的浏览和识别的图片去做推算。 所以Pinterest是需要“经营”…

网络编程概述

Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程 序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库&#xff0c;可以实现无痛的网络连接&#xff0c;联网的底层 细节被隐藏在 Java 的本机安装系统里&#xff0c;由 JVM …

权限系统设计

背景 目前只做了用户账号间的数据隔离。存在情况&#xff0c;同一个项目里不同人创建不同的资源&#xff0c;项目里的成员都可以看得到&#xff0c;同时也不能互相随便修改数据。所以需要一些组的权限控制。 1.模型和模型荚是公用的&#xff0c;没有做用户区分&#xff0c;也没…

学计算机的可以做哪些适合自己的兼职?

如果你在做以下的任意一种兼职&#xff0c;我建议你立刻停止&#xff01; 1.单纯体力劳动的兼职 像是发传单、发问卷、送外卖这类兼职只能在短期内提升你的“8小时外收入”的兼职&#xff0c;纯粹是靠时间和体力来换钱&#xff0c;性价比很低&#xff0c;而且不能通过兼职提升…

指定字符串中的一部分将原来的字符串拆分成三部分partition()函数

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 指定字符串中的一部分 将原来的字符串拆分成三部分 partition()函数 选择题 对于以下python代码表述错误的一项是? Str"12345" print("【显示】Str",Str) print("…

Vue2【前端路由的概念与原理、vue-router 的基本用法、vue-router 的常见用法、后台管理案例】

文章目录前端路由的概念与原理1. 什么是路由3. SPA 与前端路由4. 什么是前端路由5. 前端路由的工作方式6. 实现简易的前端路由步骤1&#xff1a;通过 **\<component\>** 标签&#xff0c;结合 **comName** 动态渲染组件。示例代码如下&#xff1a;步骤2&#xff1a;在 Ap…

Xcode Cloud

一、使用Xcode Cloud 的要求 &#xff08;1&#xff09;开发者账户要求 已加入Apple Developer Program向xcode加入Apple IDApp Store Connect上有app 记录或者可以创建一个app记录 &#xff08;2&#xff09;Project和workspace要求 Project或者workspace使用Xcode项目使用…

JavaScript基础语法

JavaScript基础语法 文章目录JavaScript基础语法1.JavaScript的基本认知1.1 JS的介绍与组成1.2 JS代码使用格式2.JavaScript的注释与输入输出语句2.1 JS的注释方法2.2 JS的输入输出语句3.JavaScript的变量3.1 JS的变量初始化3.2 JS的声明变量特殊情况3.3 JS的变量命名规则4.Jav…

Windows版本Anaconda安装教程

1、点击安装包&#xff0c;右键-以管理员身份运行安装文件&#xff0c;如图所示&#xff1a; 2、直接点击next即可 3、接着进入到许可协议的界面&#xff0c;这里点击I agree选项&#xff0c;也就是我同意的意思。 4、接着进入到用户选择的界面&#xff0c;选择all users选项&a…

面试官的灵魂质问—什么是转发与重定向

文章目录 文章目录文章目录[toc]一、什么是HttpServletRequest、HttpServletReSponse&#xff1f;二、Servlet中HttpServletRequest[源码](https://so.csdn.net/so/search?q源码&spm1001.2101.3001.7020)分析获取客户端传递的参数请求转发三、Servlet中HttpServletReSpons…

HTML网页设计结课作业——基于HTML+CSS仿学校官网页面

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

【保姆级】新机器部署Nacos

1、登录服务器&#xff0c;如果非root用户则切root用户 sudo su - 2、在/usr/tmp目录上传nacos安装包 3、将安装包移到/usr/local/目录 mv nacos-server-2.0.3.tar.gz /usr/local/ 4、解压 tar -zxvf nacos-server-2.0.3.tar.gz 5、创建nacos数据库&#xff0c;执行官网SQL建…