当前位置: 首页 > ds >正文

力扣每日一刷Day 19

Practice Day nineteen:Leetcode T 70

今天,我们来讲解动态规划中的最优子结构。

定义

如果一个问题的最优解包含其子问题的最优解,那么这个问题就具有最优子结构。换句话说,一个问题的最优解可以通过其子问题的最优解来构建。

 特征

  • 子问题的独立性:每个子问题的解是独立的,互不干扰。

  • 子问题的重叠性:在求解过程中,相同的子问题会被多次计算,动态规划通过存储这些子问题的解来避免重复计算。

应用

最优子结构是动态规划算法能够高效解决问题的基础。通过将问题分解为子问题,并存储子问题的解(通常使用一个表格),可以避免重复计算,从而大大提高算法的效率。

了解最优子结构后,我们就开始解答今天的题目吧

题目条件:阶梯数目、步长为1和2

题目目的:找到所给阶梯的所有方案组合数

事实上今天的是easy题,我们只拿他来理解思想,所以这是恰好的

今天我们依旧使用Leetcode的官方解答

我们知道:每做一次决定时,我们都有两种选择,两种选择为1和2(2可以拆为1和1,这实际上也算步长选取为1的一种情况,所以可以合并,故只有两种选择)。

那么我们的函数关系式可以被表示为:f(x)=f(x−1)+f(x−2)

其中x即为当前台阶编号,f(x) 表示爬到第 x 级台阶的方案数,事实上,每进行一次步进时,都可以把当前台阶序号看作最后的台阶序号,所以这个公式对最后一级台阶也是适用的。

是的,也许你会疑惑:为什么不是f(x)=f(x−1)+1+f(x−2)+1?以符合我们上面所说的,只有两种选择,每做出一种选择,方案数目就加上1?

哈哈,要像这样写f(x)=f(x−1)+1+f(x−2)+1的话,那当然也可以,但是这样未免不够美观,而且每次都需要进行额外的加2,这显然会造成算法效率的降低。如果是按这样来,我们初始化时的时候,从第零阶开始f(0)=0。

若是按f(x)=f(x−1)+f(x−2)这样来,我们的f(0)=1。可以见到,两种不同的公式,只是缘于初始化时赋的值不同。如果按f(0)=1来,每次调用f(x)时,就已经加上1了,这个1由f(0)=1提供,所以不必每次调用f(x)都像一样f(x)=f(x−1)+1+f(x−2)+1分别加上1。

你无法反驳,显然f(x)=f(x−1)+f(x−2)更加美观与迅速,不是吗?

完成了对于公式的理解后,我们需要理解f(0)的初值设置。如果你认为,f(0)到f(0)本身也算一种方案,以符合(x)=f(x−1)+f(x−2)的运行逻辑,那就应该让f(0)=1。

如果你不认为f(0)到f(0)本身不是一种方案,那他就应该符合f(x)=f(x−1)+1+f(x−2)+1的逻辑。

完成了对于公式的构建与初值的选择后,我们来进行代码的构建

由于他超简单的,所以我一次性把完整代码放出来了。

时间复杂度:O(n)

空间复杂度:O(1)

class Solution {
public:int climbStairs(int n) {int p = 0, q = 0, r = 1;for (int i = 1; i <= n; ++i) {p = q; q = r; r = p + q;}return r;}
};

由于我们只需要记录最终的方案数,且后面的计算无需查询更遥远的结果,所以我们不需要完整的容器来记录所有变量,只需要p和q,就可以分别存储f(i-1)和f(i-2)这些中间变量。

对于输出的结果,我们只需要利用一个变量 r 就可以完成对结果的储存。

对于上面的操作,他有个名称,叫做滚动数组。这是一个很有意思的数据结构,官方题解中有动画演示,没有了解过的小伙伴可以看一看,链接我会按照惯例放到题解的最后。

对于滚动数组的实现,我们通过注释来理解他

 p = q; q = r; r = p + q;
/*设当前进行的台阶序号为i*/
/*第一行的 p 代表i-2的阶梯方案数,即f(i-2)*/
/*第一行的 q 代表的是i-2的方案数,即f(i-2),这是因为进入下一台阶序号后, q 的值仍未得到更新,记录的是上一个台阶序号的方案数f(i-1),而进入下一台阶序号后,台阶编号由i-1变为i-2,故此时q记录的值是
f(i-2)*//*第二行的 q 是将上一个台阶序号的方案数,即f(i-1),赋值给q*/
/*第二行的 r 是上一个台阶的方案数*//*求当前台阶序号的方案数,即 r=f(i)=f(i-2)=p + f(i-1)=q*/

最后返回一个答案 r ,没什么好说的。

作者:力扣官方题解

链接:https://leetcode.cn/problems/climbing-stairs/solutions/286022/pa-lou-ti-by-leetcode-solution/

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

http://www.xdnf.cn/news/19657.html

相关文章:

  • 复杂计算任务的智能轮询优化实战
  • Agentless:革命性的无代理软件工程方案
  • 本地没有公网ip?用cloudflare部署内网穿透服务器,随时随地用自定义域名访问自己应用端口资源
  • 文件上传漏洞基础及挖掘流程
  • Python 爬虫实战:爬取 B 站视频的完整教程
  • TFS-2010《Fuzzy PCA-Guided Robust k-Means Clustering》
  • 控制系统仿真之PID校正-利用PID控制器、PID调节器实现(九)
  • 别再说AppInventor2只能开发安卓了!苹果iOS现已支持!
  • Linux内核内存管理系列博客教程学习规划
  • Java内功修炼(3)——并发的四重境界:单例之固、生产消费之衡、定时之准、池化之效
  • 红楼梦 AI HTML 分析 - 好了歌
  • vue动态(自适应定位)表格
  • 8.5 循环神经网络的从零开始实现
  • 运动规划实战案例 | 基于行人社交模型的移动机器人动态避障(附ROS C++仿真)
  • 交互体验升级:Three.js在设备孪生体中的实时数据响应方案
  • LintCode第401题-排序矩阵中的从小到大第k个数
  • 大数据-湖仓一体
  • Pomian语言处理器研发笔记(三):使用组合子构建抽象语法树
  • SpringBoot的基础介绍,用法和配置
  • 解锁Git仓库瘦身秘籍,git-sizer真香警告
  • GitHub 宕机自救指南:应急解决方案与替代平台
  • 复刻elementUI的步骤条Steps
  • 机器翻译:python库translatepy的详细使用(集成了多种翻译服务)
  • Redis 核心概念解析:从渐进式遍历、数据库管理到客户端通信协议
  • 自由学习记录(91)
  • C++“类吸血鬼幸存者”游戏制作的要点学习
  • 计算机毕设推荐:基于python的农产品价格数据分析与预测的可视化系统的设计与实现 基于Python农产品管理系统【源码+文档+调试】
  • 前后端联合实现多个文件上传
  • Java全栈开发面试实录:从基础到微服务架构的深度解析
  • Python 基础综合与实践教案:密码验证、循环、分支条件、图形绘制