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

漳州市网站建设_网站建设公司_MySQL_seo优化

石家庄的电商网站建设,申请域名需要多久,清理wordpress模板,门户导航网页模板动态规划#xff0c;英文#xff1a;Dynamic Programming#xff0c;简称DP#xff0c;如果某一问题有很多重叠子问题#xff0c;使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的#xff0c;这一点就区分于贪心#xff0c;贪心没有状态推…动态规划英文Dynamic Programming简称DP如果某一问题有很多重叠子问题使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的这一点就区分于贪心贪心没有状态推导而是从局部直接选最优的。 动态规划的解题步骤 状态转移公式递推公式是很重要但动规不仅仅只有递推公式。 对于动态规划问题我将拆解为如下五步曲这五步都搞清楚了才能说把动态规划真的掌握了 确定dp数组dp table以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 一些同学可能想为什么要先确定递推公式然后在考虑初始化呢 因为一些情况是递推公式决定了dp数组要如何初始化 动态规划应该如何debug 找问题的最好方式就是把dp数组打印出来看看究竟是不是按照自己思路推导的 一些同学对于dp的学习是黑盒的状态就是不清楚dp数组的含义不懂为什么这么初始化递推公式背下来了遍历顺序靠习惯就是这么写的然后一鼓作气写出代码如果代码能通过万事大吉通过不了的话就凭感觉改一改。 这是一个很不好的习惯 做动规的题目写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍心中有数确定最后推出的是想要的结果。 然后再写代码如果代码没通过就打印dp数组看看是不是和自己预先推导的哪里不一样。 如果打印出来和自己预先模拟推导是一样的那么就是自己的递归公式、初始化或者遍历顺序有问题了。 如果和自己预先模拟推导的不一样那么就是代码实现细节有问题。 这样才是一个完整的思考过程而不是一旦代码出问题就毫无头绪的东改改西改改最后过不了或者说是稀里糊涂的过了。 这也是我为什么在动规五步曲里强调推导dp数组的重要性。 举个例子哈在「代码随想录」刷题小分队微信群里一些录友可能代码通过不了会把代码抛到讨论群里问我这里代码都已经和题解一模一样了为什么通过不了呢 发出这样的问题之前其实可以自己先思考这三个问题 这道题目我举例推导状态转移公式了么我打印dp数组的日志了么打印出来了dp数组和我想的一样么 如果这灵魂三问自己都做到了基本上这道题目也就解决了或者更清晰的知道自己究竟是哪一点不明白是状态转移不明白还是实现代码不知道该怎么写还是不理解遍历dp数组的顺序。 然后在问问题目的性就很强了群里的小伙伴也可以快速知道提问者的疑惑了。 注意这里不是说不让大家问问题哈 而是说问问题之前要有自己的思考问题要问到点子上 509. 斐波那契数 力扣题目链接 斐波那契数通常用 F(n) 表示形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始后面的每一项数字都是前面两项数字的和。也就是 F(0) 0F(1) 1 F(n) F(n - 1) F(n - 2)其中 n 1 给你n 请计算 F(n) 。 示例 1 输入2输出1解释F(2) F(1) F(0) 1 0 1 示例 2 输入3输出2解释F(3) F(2) F(1) 1 1 2 示例 3 输入4输出3解释F(4) F(3) F(2) 2 1 3 提示 0 n 30 动态规划 动规五部曲 这里我们要用一个一维dp数组来保存递归的结果 确定dp数组以及下标的含义 dp[i]的定义为第i个数的斐波那契数值是dp[i] 确定递推公式 为什么这是一道非常简单的入门题目呢 因为题目已经把递推公式直接给我们了状态转移方程 dp[i] dp[i - 1] dp[i - 2]; dp数组如何初始化 题目中把如何初始化也直接给我们了如下 dp[0] 0; dp[1] 1;1.确定遍历顺序 从递归公式dp[i] dp[i - 1] dp[i - 2];中可以看出dp[i]是依赖 dp[i - 1] 和 dp[i - 2]那么遍历的顺序一定是从前到后遍历的 2.举例推导dp数组 按照这个递推公式dp[i] dp[i - 1] dp[i - 2]我们来推导一下当N为10的时候dp数组应该是如下的数列 0 1 1 2 3 5 8 13 21 34 55 如果代码写出来发现结果不对就把dp数组打印出来看看和我们推导的数列是不是一致的。 以上我们用动规的方法分析完了代码如下 class Solution {public int fib(int n) {if(n1) return n;int[] dpnew int[n1];dp[0]0;dp[1]1;for(int i2;in;i){dp[i]dp[i-1]dp[i-2];}return dp[n];} }时间复杂度O(n)空间复杂度O(n) 当然可以发现我们只需要维护两个数值就可以了不需要记录整个序列。 代码如下 class Solution {public int fib(int n) {if (n 2) return n;int a 0, b 1, c 0;for (int i 1; i n; i) {c a b;a b;b c;}return c;} }时间复杂度O(n)空间复杂度O(1) 70. 爬楼梯 力扣题目链接 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢 注意给定 n 是一个正整数。 示例 1 输入 2输出 2解释 有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示例 2 输入 3输出 3解释 有三种方法可以爬到楼顶。 1 阶 1 阶 1 阶1 阶 2 阶2 阶 1 阶 我们来分析一下动规五部曲 定义一个一维数组来记录不同楼层的状态 1.确定dp数组以及下标的含义 dp[i] 爬到第i层楼梯有dp[i]种方法 2.确定递推公式 dp[i] 可以有两个方向推出来。 首先是dp[i - 1]上i-1层楼梯有dp[i - 1]种方法那么再一步跳一个台阶不就是dp[i]了么。 还有就是dp[i - 2]上i-2层楼梯有dp[i - 2]种方法那么再一步跳两个台阶不就是dp[i]了么。 那么dp[i]就是 dp[i - 1]与dp[i - 2]之和 所以dp[i] dp[i - 1] dp[i - 2] 。 3.dp数组如何初始化 再回顾一下dp[i]的定义爬到第i层楼梯有dp[i]种方法。 本题其实就不应该讨论dp[0]的初始化 我相信dp[1] 1dp[2] 2这个初始化大家应该都没有争议的。 所以我的原则是不考虑dp[0]如何初始化只初始化dp[1] 1dp[2] 2然后从i 3开始递推这样才符合dp[i]的定义。 4.确定遍历顺序 从递推公式dp[i] dp[i - 1] dp[i - 2];中可以看出遍历顺序一定是从前向后遍历的 5.举例推导dp数组 举例当n为5的时候dp tabledp数组应该是这样的 如果代码出问题了就把dp table 打印出来看看究竟是不是和自己推导的一样。 此时大家应该发现了这不就是斐波那契数列么 唯一的区别是没有讨论dp[0]应该是什么因为dp[0]在本题没有意义 以上五部分析完之后C代码如下 class Solution {public int climbStairs(int n) {if(n1) return n;int[] dpnew int[n1];dp[1]1;dp[2]2;for(int i3;in;i){dp[i]dp[i-2]dp[i-1];}return dp[n];} } 时间复杂度O(n)空间复杂度O(n) 当然依然也可以优化一下空间复杂度代码如下 class Solution {public int climbStairs(int n) {if(n1) return n;int a1;int b2;int sum0;for(int i3;in;i){sumab;ab;bsum;}return b;} }时间复杂度 O ( n ) O(n) O(n)空间复杂度 O ( 1 ) O(1) O(1) 746. 使用最小花费爬楼梯 力扣题目链接 数组的每个下标作为一个阶梯第 i 个阶梯对应着一个非负数的体力花费值 cost[i]下标从 0 开始。 每当你爬上一个阶梯你都要花费对应的体力值一旦支付了相应的体力值你就可以选择向上爬一个阶梯或者爬两个阶梯。 请你找出达到楼层顶部的最低花费。在开始时你可以选择从下标为 0 或 1 的元素作为初始阶梯。 示例 1 输入cost [10, 15, 20]输出15解释最低花费是从 cost[1] 开始然后走两步即可到阶梯顶一共花费 15 。 示例 2 输入cost [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]输出6解释最低花费方式是从 cost[0] 开始逐个经过那些 1 跳过 cost[3] 一共花费 6 。 提示 cost 的长度范围是 [2, 1000]。cost[i] 将会是一个整型数据范围为 [0, 999] 。 思路 在力扣修改了题目描述下我又重新修改了题解 修改之后的题意就比较明确了题目中说 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯” 也就是相当于 跳到 下标 0 或者 下标 1 是不花费体力的 从 下标 0 下标1 开始跳就要花费体力了。 1.确定dp数组以及下标的含义 使用动态规划就要有一个数组来记录状态本题只需要一个一维数组dp[i]就可以了。 dp[i]的定义到达第i台阶所花费的最少体力为dp[i]。 2.确定递推公式 可以有两个途径得到dp[i]一个是dp[i-1] 一个是dp[i-2]。 dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] cost[i - 1]。 dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] cost[i - 2]。 那么究竟是选从dp[i - 1]跳还是从dp[i - 2]跳呢 一定是选最小的所以dp[i] min(dp[i - 1] cost[i - 1], dp[i - 2] cost[i - 2]); 3.dp数组如何初始化 新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的但从 第0 个台阶 往上跳的话需要花费 cost[0]。 所以初始化 dp[0] 0dp[1] 0; 4.确定遍历顺序 因为是模拟台阶而且dp[i]由dp[i-1]dp[i-2]推出所以是从前到后遍历cost数组就可以了。 5.举例推导dp数组 拿示例2cost [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 来模拟一下dp数组的状态变化如下 如果大家代码写出来有问题就把dp数组打印出来看看和如上推导的是不是一样的。 以上分析完毕整体代码如下 class Solution {public int minCostClimbingStairs(int[] cost) {int[] dpnew int[cost.length1];dp[0]0;dp[1]0;for(int i2;icost.length;i){dp[i]Math.min(dp[i-1]cost[i-1],dp[i-2]cost[i-2]);}return dp[cost.length];} }时间复杂度O(n)空间复杂度O(n) 还可以优化空间复杂度因为dp[i]就是由前两位推出来的那么也不用dp数组了C代码如下 class Solution {public int minCostClimbingStairs(int[] cost) {int dp00;int dp10;for(int i2;icost.length;i){int dpiMath.min(dp1cost[i-1],dp0cost[i-2]);dp0dp1;dp1dpi;}return dp1;} }时间复杂度O(n)空间复杂度O(1) 当然如果在面试中能写出版本一就行除非面试官额外要求 空间复杂度那么再去思考版本二因为版本二还是有点绕。版本一才是正常思路。
http://www.lebaoying.cn/news/4410.html

相关文章:

  • 图片库网站建设报价优秀的网站建设解决方案
  • 网站备案名称能重复吗wordpress跳转外部链接
  • 南充建设机械网站网站推广营销怎么做
  • 政务网站开发去三亚要下载什么app?
  • 给你一个网站你怎么做的找个美工做淘宝网站需要多少钱
  • 网站开发外贸网站制作 台州
  • 论医院网站的建设做网站的具体步骤
  • 旅游网站建设的原因北京壹零零壹网站建设
  • 淮安公司企业网站建设制作网页的教程
  • 单位建设网站硬件wordpress国内医疗
  • 网站关键词排名优化工具网站开发免责声明
  • 郑州企业建设网站有什么用企业网站建设之域名篇
  • qq炫舞做字网站深圳市住建局官网查询
  • 怎么注册英文网站域名桂林网站开发建设
  • 小卖部做网站淘宝网页版登录电脑版
  • 网站建设的原则有哪些内容wordpress wp rss
  • 网站开发需要什么服务器地方门户网站的前途
  • 建设网站需要多少费用龙岩天宫山住宿怎么订
  • 网站开发技术的背景静态网页怎么放到网上
  • 为什么在百度搜不到我的网站wordpress每篇文章加固定文字
  • 网站建设平台ui确认书静态化网站和app的区别
  • php怎么做直播网站吗莱芜区政协网站
  • 漂亮的网站改版中 html代码个人网页设计作品 html模版
  • 牡丹江建设工程信息网站做兼职工作上哪个网站招聘
  • 网站滑动效果怎么做的wordpress搭建像册
  • 宁波比较好的网站公司佛山新网站建设代理商
  • 怎么在静态网站基础上加动态用php做网站的方法
  • 视频网站做板块栏目app研发录
  • 个人网站如何建设移动wifi多少钱一个月
  • 浦西网站建设万网主机建wordpress