【力扣】从零开始的动态规划

【力扣】从零开始的动态规划

文章目录

  • 【力扣】从零开始的动态规划
    • 开头
    • 139. 单词拆分
      • 解题思路
    • 45. 跳跃游戏 II
      • 解题思路
    • 5. 最长回文子串
      • 解题思路
    • 1143. 最长公共子序列
      • 解题思路
    • 931. 下降路径最小和
      • 解题思路

开头

本力扣题解用5题来引出动态规划的解题步骤,用于本人进阶掌握动态规划,在刷题过程中写下的一些解题步骤与思路,供大家一起学习

139. 单词拆分

139. 单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s

**注意:**不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

解题思路

状态表示: dp[i]表示字符串以0到i-1的字符串,能否组成字串

初始状态:dp[0]=true,没有字符串的情况肯定为true,如果这个为false,那么后面全部为false

状态转移方程:

​ 可以把一个字符串来看成两段,0~j-1j~i,前面一半可以看成dp[j],因为看下状态表示就知道了,dp[i]表示字符串以0到i-1的字符串, 带入j得dp[j]表示字符串以0到j-1的字符串。

​ 后一半直接在哈希表中找子串是否存在,找到了就是true,如果两个字串同时为true,那么dp[i]=true

​ 因为以0~i的字符串的分解的情况有很多种,只要其中一种为true,那么就是true,直接break

​ 所以动态转移方程为:

            if(dp[j] && set.contains(s.substring(j,i))){dp[i]=true;break;}
import java.util.HashSet;
import java.util.Set;class Solution {public boolean wordBreak(String s, List<String> wordDict) {Set<String> set=new HashSet<>(wordDict);int n=s.length();boolean[] dp=new boolean[n+1];dp[0]=true;//从第i个字符结束的for(int i=0;i<=n;i++){for(int j=0;j<i;j++){if(dp[j] && set.contains(s.substring(j,i))){dp[i]=true;break;}}}return dp[n];}
}

45. 跳跃游戏 II

45. 跳跃游戏 II

给定一个长度为 n0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

解题思路

状态表示: dp[i]表示从1开始跳到第i个数的最小次数

​ **初始状态:**第1个元素是起点,可以到达,其他所有结点默认无法到达,设置一个很大的初始值

状态转移方程:

​ 第i个数可以从前面任意一个跳跃距离大于两个结点距离的结点,及判断条件if(nums[j]>=i-j),在这些满足要求的结点中取最小值,方程为

dp[i]=min(dp[0],dp[1],dp[2]...dp[n-1])+1,写成循环结构,最终方程为:dp[i]=Math.min(dp[i],dp[j]+1);

import java.util.Arrays;class Solution {public int jump(int[] nums) {int n=nums.length;int[] dp=new int[n];Arrays.fill(dp,Integer.MAX_VALUE);//状态表示:前跳到第i个的最小次数dp[0]=0;for(int i=1;i<n;i++){for(int j=0;j<i;j++){int l=i-j;if(nums[j]>=l){dp[i]=Math.min(dp[i],dp[j]+1);}}}return dp[n-1];}
}

5. 最长回文子串

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

解题思路

状态表示: dp[i][j] 表示 i到j是否是一个回文串

​ **初始状态:**无

状态转移方程:

​ 想要知道dp[i][j]是否是一个回文子串,只需知道dp[i+1][j-1]是否是一个回文子串并且外层的字符相等即s[i]==s[j],那么dp[i][j]就是一个回文子串,还有一种特殊情况是:要判断的字符串只有两个字符时,不用再判断dp[i+1][j-1]是否是一个回文子串,只需判断这两个字符是否相等即可

​ **循环顺序:**想要知道循环顺序是从大到小,还是从小到大,我们要知道dp数组中哪个要先算出来 ,哪个后算出来,比如想要知道dp[i][j]是否是一个回文子串,就得先知道dp[i+1][j-1]是否也是一个回文子串,所以dp[i+1][j-1]要被先计算出来,分为两重循环来分析

​ 外重循环i+1比i要先知道,所以,i从大到小循环

​ 内重循环j-1比j要先知道,所以j从小到大循环

​ 又因为j一定要大于等于i,因为范围表示是i~j,所以j从i到n-1

            if(s.charAt(i)==s.charAt(j)){if(j-i<2 || dp[i+1][j-1] )dp[i][j]=true;}
class Solution {public String longestPalindrome(String s) {int n=s.length();//状态表示:i到j是否是一个回文串boolean[][] dp=new boolean[n][n];//dp[i][j]=dp[i+1][j-1] && s.charAt(i)==s.charAt(j)String str="";for(int i=n-1;i>=0;i--){for(int j=i;j<n;j++){if(s.charAt(i)==s.charAt(j)){if(j-i<2 || dp[i+1][j-1] )dp[i][j]=true;}if(dp[i][j] && (j-i+1)>str.length()){str=s.substring(i,j+1);}}}return str;}
}

1143. 最长公共子序列

1143. 最长公共子序列

给定两个字符串 text1text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,"ace""abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

解题思路

状态表示:dp[i][j] 表示 text1[0:i-1]text2[0:j-1] 的最长公共子序列

**状态转移方程:**知道状态定义之后,我们开始写状态转移方程。

​ 当 text1[i - 1] == text2[j - 1] 时,说明两个子字符串的最后一位相等,所以最长公共子序列又增加了 1,所以 dp[i][j] = dp[i - 1][j - 1] + 1;举个例子,比如对于 ac 和 bc 而言,他们的最长公共子序列的长度等于 a 和 b 的最长公共子序列长度 0 + 1 = 1。
text1[i - 1] != text2[j - 1] 时,说明两个子字符串的最后一位不相等,那么此时的状态 dp[i][j] 应该是 dp[i - 1][j]dp[i][j - 1] 的最大值。举个例子,比如对于 ac和 bc 而言,他们的最长公共子序列的长度等于 ① ace 和 b 的最长公共子序列长度0 与 ② ac 和 bc 的最长公共子序列长度1 的最大值,即 1。

​ 所以状态转移方程为:当text[i-1]==text[j-1]时.dp[i][j]=dp[i-1][j-1]+1

​ 当text[i-1]!=text[j-1]时,dp[i][j]=max(dp[i−1][j],dp[i][j−1])

**初始值:**初始化就是要看当 i = 0 与 j = 0 时, dp[i][j] 应该取值为多少。

当 i = 0 时,dp[0][j] 表示的是 text1 中取空字符串 跟 text2 的最长公共子序列,结果肯定为 0.
当 j = 0 时,dp[i][0] 表示的是 text2 中取空字符串 跟 text1 的最长公共子序列,结果肯定为 0.
综上,当 i = 0 或者 j = 0 时,dp[i][j] 初始化为 0.

遍历方向与范围:由于 dp[i][j] 依赖与 dp[i - 1][j - 1] , dp[i - 1][j], dp[i][j - 1],所以 iii 和 jjj 的遍历顺序肯定是从小到大的。 另外,由于当 i 和 j 取值为 0 的时候,dp[i][j] = 0,而 dp 数组本身初始化就是为 0,所以,直接让 i 和 j 从 1 开始遍历。遍历的结束应该是字符串的长度为 len(text1) 和 len(text2)

class Solution {public int longestCommonSubsequence(String text1, String text2) {int n=text1.length();int m=text2.length();int[][] dp=new int[n+1][m+1];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(text1.charAt(i-1)==text2.charAt(j-1))dp[i][j]=dp[i-1][j-1]+1;elsedp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);}}return dp[n][m];}
}

931. 下降路径最小和

931. 下降路径最小和

给你一个 n x n方形 整数数组 matrix ,请你找出并返回通过 matrix下降路径最小和

下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)(row + 1, col) 或者 (row + 1, col + 1)

示例 1:

img

输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释:如图所示,为和最小的两条下降路径

解题思路

状态表示:dp[i][j]表示走到matrix[i][j]的最小下降和

**初始值:**第一行全是0,因为在原地(起点)

**状态转移方程:**到达dp[i][j]可以从上一层的相邻元素到达,取其中的最小值并加上一步的数量,即dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+matrix[i][j],因为要判断边界条件,在最左边和最右边只能从上一层的两个到达。

​ 综上所诉,状态转移方程为:

if(j==0)dp[i][j]=Math.min(dp[i-1][j],dp[i-1][j+1])+matrix[i][j];
else if(j==m-1)dp[i][j]=Math.min(dp[i-1][j-1],dp[i-1][j])+matrix[i][j];
elsedp[i][j]=Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i-1][j+1]))+matrix[i][j];

**答案:**根据题目要求,到达最后一行的最少下降和,再看状态表示:dp[i][j]表示走到matrix[i][j]的最小下降和,所以答案就在dp的最后一行中,取最后一行的最小值即是答案

class Solution {public int minFallingPathSum(int[][] matrix) {int n=matrix.length;int m=matrix[0].length;int[][] dp=new int[n][m];for(int j=0;j<m;j++){dp[0][j]=matrix[0][j];}for(int i=1;i<n;i++){for(int j=0;j<m;j++){if(j==0)dp[i][j]=Math.min(dp[i-1][j],dp[i-1][j+1])+matrix[i][j];else if(j==m-1)dp[i][j]=Math.min(dp[i-1][j-1],dp[i-1][j])+matrix[i][j];elsedp[i][j]=Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i-1][j+1]))+matrix[i][j];}}int min=Integer.MAX_VALUE;for(int j=0;j<m;j++){min=Math.min(min,dp[n-1][j]);}return min;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 目标检测-行人车辆检测流量计数

文章目录 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 行人车辆目标检测计数系统 …

【计算机网络笔记】路由算法之距离向量路由算法

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

DAY60 84.柱状图中最大的矩形

84.柱状图中最大的矩形 题目要求&#xff1a;给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 思路 单调栈 本地单调栈的解法和接雨水的题目是遥相呼…

【docker】虚拟化和docker容器概念

基础了解 IAAS&#xff1a; 基础设施服务&#xff0c;&#xff08;只提供基础设施&#xff0c;没有系统&#xff09; **SAAS&#xff1a; ** 软件即服务&#xff0c;&#xff08;提供基础设施和系统&#xff09; PAAS&#xff1a; 平台即服务&#xff0c;&#xff08;提供基…

《白帽子讲web安全》

第十四章 PHP安全 文件包含漏洞是“代码注入”的一种。“代码注入”这种攻击&#xff0c;其原理就是注入一段用户能控制的脚本或代码&#xff0c;并让服务器端执行。“代码注入”的典型代表就是文件包含&#xff08;File Inclusion&#xff09;。文件包含可能会出现在JSP、PHP…

时序预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的时间序列预测

时序预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的时间序列预测 目录 时序预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现HPO-ELM猎食者算法优化极限学习机时间序列预测 1.data为数据集…

【C++ 学习 ㊴】- 详解 C++ 的 I/O 流

目录 一、C 的 I/O 流 二、C 的标准 I/O 流 三、C 的文件 I/O 流 一、C 的 I/O 流 C 语言有一套完成数据读写&#xff08;I/O&#xff09;的解决方案&#xff1a; 使用 scanf()、gets() 等函数从键盘读取数据&#xff0c;使用 printf()、puts() 等函数向屏幕输出数据&#…

②【Hash】Redis常用数据类型:Hash [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis Hash ②Redis Hash 操作命令汇总1. hset…

Week-T10 数据增强

文章目录 一、准备环境和数据1.环境2. 数据 二、数据增强&#xff08;增加数据集中样本的多样性&#xff09;三、将增强后的数据添加到模型中四、开始训练五、自定义增强函数六、一些增强函数 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f…

【Java】异常处理及其语法、抛出异常、自定义异常(完结)

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;Java ⭐每日一句&#xff1a;道阻且长&#xff0c;行则将至 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 一.&#x1f510;异…

Java,数据结构与集合源码,数据结构概述

目录 数据结构概念&#xff1a; 数据结构的研究对象&#xff1a; 研究对象一&#xff0c;数据间逻辑关系&#xff1a; 研究对象二&#xff0c;数据的存储结构&#xff08;或物理结构&#xff09;&#xff1a; 研究对象三&#xff1a;运算结构 数据结构的相关介绍&#xff…

maven pom引入依赖不报红,但是项目Dependencies中没有引入jar包

前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注一下&#xff01; 也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff0c;才能走的更远&#xff01;让我们在成长的道路上互相学习&…

vue中data属性为什么是一个函数?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue-data属性 目录 为什么data属性是一个函数而不是一个对象&#xff1f; 一、实例和组件定义dat…

Apache Airflow (十三) :Airflow分布式集群搭建及使用-原因及

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

U4_1:图论之DFS/BFS/TS/Scc

文章目录 一、图的基本概念二、广度优先搜索&#xff08;BFS&#xff09;记录伪代码时间复杂度流程应用 三、深度优先搜索&#xff08;DFS&#xff09;记录伪代码时间复杂度流程时间戳结构BFS和DFS比较 四、拓扑排序一些概念有向图作用拓扑排序 分析伪代码时间复杂度彩蛋 五、强…

复杂数据统计与R语言程序设计实验一

1.下载并安装R语言软件&#xff0c;熟悉基本操作的命令及操作界面&#xff0c;掌握软件的使用方法&#xff08;提供学号加姓名的截图&#xff09;。 2.下载并安装Rstudio&#xff0c; &#xff08;提供运行代码及运行结果的截图&#xff09;。 3.下载并安装R包DT&#xff0c;…

树莓派的的串口通信协议

首先&#xff0c;回顾一下串口的核心知识点&#xff0c;也是面试重点&#xff1a; 串口通信通常使用在多机通讯中串口通信是全双工的决定串口通信的成功与否的是 数据格式 和 波特率数据格式&#xff1a;1. 数据位 2.停止位 3. 奇偶校验位 树莓派恢复串口 回忆前几节树莓派刷机…

Tensorrt 实现 yolov5-cls 遇到的问题

yolov5-6.2增加了分类训练、验证、预测和导出&#xff08;所有 11 种格式&#xff09;&#xff0c;还提供了 ImageNet 预训练的 YOLOv5m-cls、ResNet&#xff08;18、34、50、101) 和 EfficientNet (b0-b3) 模型. 官方Git : https://github.com/ultralytics/yolov5 分类模型与…

企业微信将应用安装到工作台

在上篇中介绍了配置小程序应用及指令、数据回调获取第三方凭证&#xff1b; 本篇将介绍如何将应用安装到企业工作台。 添加测试企业 通过【应用管理】->【测试企业配置】添加测试企业。 通过企业微信扫描二维码添加测试企业。 注意&#xff1a;需要扫描的账号为管理员权限…

4.Gin HTML 模板渲染

4.Gin HTML 模板渲染 Gin HTML 模板渲染 1. 全部模板放在一个目录里面的配置方法 创建用于渲染的模板html templates/index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> …