动态规划算法专题(六):回文串问题

目录

1、回文子串("引子题")

1.1 算法原理 

1.2 算法代码

2、最长回文子串

2.1 算法原理

2.2 算法代码

3、分割回文串 IV(hard)

3.1 算法原理

3.2 算法代码

4、分割字符串 II(hard)

4.1 算法原理 

4.2 算法代码

5、最长回文子序列

5.1 算法原理 

5.2 算法代码

6、让字符串成为回文串的最少插入次数(hard)

6.1 算法原理

6.2 算法代码


1、回文子串("引子题")

. - 力扣(LeetCode)

1.1 算法原理 

  • 状态表示:

dp[i][j]:[i, j]区间内的子串,是否回文(i <= j)

  • 状态转移方程:

s[i] == s[j]:

1. i == j --> true 
2. i+1==j --> s(i) == s(j) ? true : false
3. s(i) == s(j) --> dp[i+1][j-1]

  • 初始化:

无需初始化(状态转移方程的前两种情况已处理特殊的边界情况)

  • 建表顺序:

从下往上(根据状态转移方程)

  • 返回值:

dp表中有几个true

1.2 算法代码

class Solution {public int countSubstrings(String ss) {char[] s = ss.toCharArray();int n = s.length;boolean[][] dp = new boolean[n][n];int ret = 0;// 填表 --> 从下往上for(int i = n - 1; i >= 0; i--) {// j >= ifor(int j = i; j < n; j++) {if(s[i] == s[j]) {if(i == j) dp[i][j] = true;else if(i + 1 == j) dp[i][j] = true;else dp[i][j] = dp[i + 1][j - 1];}if(dp[i][j]) ret++;}}return ret;}
}

2、最长回文子串

. - 力扣(LeetCode)

2.1 算法原理

本题算法原理与题一完全一致,最终返回最长的回文子串即可。

  • 状态表示:

dp[i][j]:[i, j]区间内的子串,是否回文(i <= j)

  • 状态转移方程:

s[i] == s[j]:

1. i == j --> true 
2. i+1==j --> s(i) == s(j) ? true : false
3. s(i) == s(j) --> dp[i+1][j-1]

  • 初始化:

无需初始化(状态转移方程的前两种情况已处理特殊的边界情况)

  • 建表顺序:

从下往上(根据状态转移方程)

  • 返回值:

最长回文子串

2.2 算法代码

class Solution {public String longestPalindrome(String ss) {char[] s = ss.toCharArray();int n = s.length;boolean[][] dp = new boolean[n][n];String ret = "";int begin = 0;int end = 0;// 建表 --> 从下往上for(int i = n - 1; i >= 0; i--) {for(int j = i; j < n; j++) {// i <= jif(s[i] == s[j]) {if(i == j) dp[i][j] = true;else if(i + 1 == j) dp[i][j] = true;else dp[i][j] = dp[i + 1][j - 1];}if(dp[i][j]) {// 记录最长回文子串的起始和末尾位置if(j - i + 1 > end - begin + 1) {begin = i;end = j;}} }}return ss.substring(begin, end + 1);}
}

3、分割回文串 IV(hard)

. - 力扣(LeetCode)

3.1 算法原理

本题算法原理依旧是在题一判断好哪些子串是回文的基础上,分割字符串,判断是否存在三个回文串即可。

  • 状态表示:

dp[i][j]:[i, j]区间内的子串,是否回文(i <= j)

  • 状态转移方程:

s[i] == s[j]:

1. i == j --> true 
2. i+1==j --> s(i) == s(j) ? true : false
3. s(i) == s(j) --> dp[i+1][j-1]

  • 初始化:

无需初始化(状态转移方程的前两种情况已处理特殊的边界情况)

  • 建表顺序:

从下往上(根据状态转移方程)

  • 返回值:

是否存在三个回文串。

3.2 算法代码

class Solution {public boolean checkPartitioning(String ss) {char[] s = ss.toCharArray();int n = s.length;boolean[][] dp = new boolean[n][n];for(int i = n - 1; i >= 0; i--) {for(int j = i; j < n; j++) {if(s[i] == s[j]) {if(i == j) dp[i][j] = true;else if(i + 1 == j) dp[i][j] = true;else dp[i][j] = dp[i + 1][j - 1];}}}// 从 i,j 位置 分割字符串for(int i = 1; i < n; i++) {for(int j = i; j < n - 1; j++) {if(dp[0][i - 1] && dp[i][j] && dp[j + 1][n - 1]) return true;}}return false;}
}

4、分割字符串 II(hard)

. - 力扣(LeetCode)

4.1 算法原理 

本题仍然在题一中 通过二维dp保存所有子串的是否回文的信息 的基础上解题。

  • 状态表示:

dp[i]:以[0, i]区间内的子串,最少的分割次数

  • 状态转移方程:

1. 0~i 回文 --> 0
2. 0~i 不回文 --> 0 < j < = i --> 若子串[ j, i ]回文 --> min(dp[ j - 1 ] + 1)

  • 初始化:

dp表中所有元素初始化为Integer.MAX_VALUE

  • 建表顺序:

从左往右

  • 返回值:

dp[n-1]

4.2 算法代码

class Solution {public int minCut(String ss) {char[] s = ss.toCharArray();int n = s.length;boolean[][] isPal = new boolean[n][n];for (int i = n - 1; i >= 0; i--) {for (int j = i; j < n; j++) {if (s[i] == s[j]) {if (i == j)isPal[i][j] = true;else if (i + 1 == j)isPal[i][j] = true;elseisPal[i][j] = isPal[i + 1][j - 1];}}}int[] dp = new int[n];// 初始化Arrays.fill(dp, Integer.MAX_VALUE);for (int i = 0; i < n; i++) {if (isPal[0][i])dp[i] = 0;else {// j --> (0, i]for (int j = 1; j <= i; j++) {if (isPal[j][i])dp[i] = Math.min(dp[i], dp[j - 1] + 1);}}}return dp[n - 1];}
}

5、最长回文子序列

. - 力扣(LeetCode)

5.1 算法原理 

  • 状态表示:

dp[i][j]:s字符串[i , j]区间内的所有子序列中,最长回文子序列的长度

  • 状态转移方程:

1. s[i] == s[j]:

i==j --> 1
i+1==j --> 2
dp[i+1][j-1]+2

2. s[i] != s[j]:

max(dp[i][j-1], dp[i+1][j])

  • 初始化:

无需初始化

  • 建表顺序:

从下往上填写每一行,每一行从左往右填写每一列

  • 返回值:

dp[0][n-1]

5.2 算法代码

class Solution {public int longestPalindromeSubseq(String ss) {char[] s = ss.toCharArray();int n = s.length;int[][] dp = new int[n][n];// 从下往上填每一行// 每一行从左往右填每一列for(int i = n - 1; i >= 0; i--) {for(int j = i; j < n; j++) {if(s[i] == s[j]) {if(i == j) dp[i][j] = 1;else if(i + 1 == j) dp[i][j] = 2;else dp[i][j] = dp[i + 1][j - 1] + 2;}else {dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);}}}return dp[0][n - 1];}
}

6、让字符串成为回文串的最少插入次数(hard)

. - 力扣(LeetCode)

6.1 算法原理

  • 状态表示:

dp[i][j]:字符串[i, j]区间内的子串,使它成为回文串的最小插入次数

  • 状态转移方程:

s[i] == s[j]:

1. i == j --> 0

2. i + 1 == j --> 0

3. dp[i + 1][j - 1]

s[i] != s[j]:

min(dp[i + 1][j], dp[i][j - 1]) + 1;

  • 初始化:

无需初始化

  • 建表顺序:

从上到下每一行
从左往右每一列

  • 返回值:

dp[0][n-1]

6.2 算法代码

class Solution {public int minInsertions(String ss) {char[] s = ss.toCharArray();int n = s.length;int[][] dp = new int[n][n];// 无需初始化// 建表 --> 从上往下每一行,从左往右每一列for(int i = n - 1; i >= 0; i--) {for(int j = i; j < n; j++) {if(s[i] == s[j]) {if(i == j) dp[i][j] = 0;else if(i + 1 == j) dp[i][j] = 0;else dp[i][j] = dp[i + 1][j - 1];}else dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + 1;}}return dp[0][n - 1];}
}

END

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

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

相关文章

Spring Boot教学资源库:开发者的成长之路

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

AI视频技术复活老照片-简单快捷

准备老照片 可在网上搜索“老照片”图片&#xff0c;选择人物背景全的图片 照片修复 腾讯的ARC Lab网站 https://arc.tencent.com/zh/ai-demos/faceRestoration 上传照片&#xff0c;修复后下载&#xff0c;会直接在浏览器中下载 AI视频生成 采用可灵网&#xff1a; http…

PGMP-05相关方

目录 1.主要内容 2.概括 3.相关方人员 1.主要内容 Stakeholders IdentificationStakeholders AnalysisStakeholders Engagement PlanningStakeholders EngagementStakeholder communications 2.概括 识别&#xff1a;产生相关方登记册&#xff0c;使用头脑风暴分析&#x…

深入理解Transformer的笔记记录(精简版本)----Seq2Seq → Seq2Seq with Attention

只要是符合类似的框架,都可以统称为 Encoder-Decoder 模型。 1、RNN RNN引入了隐状态h(hidden state)的概念,隐状态h可以对序列形的数据提取特征,接着再转换为输出。 x1,x2,x3,x4如: 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推语音处…

2024 闽盾杯-黑盾赛道WP

CRYPTO 签到题-学会SM https://www.json.cn/encrypt/sm3 题目要求小写所以需要转换一下 或者脚本&#xff1a; import hashlib message "heidun2024" hash_object hashlib.new(sm3) hash_object.update(message.encode(utf-8)) hash_value hash_object.hexdigest(…

AI助力智慧农田作物病虫害监测,基于YOLOv9全系列【yolov9/t/s/m/c/e】参数模型开发构建花田作物种植场景下棉花作物常见病虫害检测识别系统

智慧农业是一个很大的应用市场&#xff0c;将当下如火如荼的AI模型技术与现实的农业生产场景相结合能够有效提升生产效率&#xff0c;农作物在整个种植周期中有很多工作需要进行&#xff0c;如&#xff1a;浇水、施肥、除草除虫等等&#xff0c;传统的农业作物种植生产管理周期…

带你走近CCV(一)

从事多媒体互动行业8年了&#xff0c;最近才想着自己可以独自写一个识别软件&#xff0c;应该说想把公司里的识别统统临摹一遍&#xff0c;这样在接外包的时候可以游刃有余了 什么是CCV&#xff1f; CCV是一个建立在openCV基础上的一个开源的架构&#xff0c;其全称是Communit…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置)

SpringBoot教程&#xff08;二十四&#xff09; | SpringBoot实现分布式定时任务之Quartz&#xff08;多数据源配置&#xff09; 前言多数据源配置引入aop依赖1. properties配置多数据源2. 创建数据源枚举类3. 线程参数配置类4. 数据源动态切换类5. 多数据源配置类HikariCP 版本…

Java基础(2) 之面向对象

文章目录 Java基础(2) 之面向对象1.对象2.类类的注意事项 3.this关键字4.构造器注意 5.封装性6.实体JavaBean实体类 7.成员变量和局部变量的区别8.staticstatic修饰成员变量static修饰成员方法static的注意事项工具类单例设计模式 9.代码块静态代码块实例代码块 10.继承权限修饰…

Springboot——使用poi实现excel动态图片导入解析

文章目录 前言依赖引入导入实现方式一方式二 前言 最近要实现一个导入导出的功能点&#xff0c;需要能将带图片的列表数据导出到excel中&#xff0c;且可以导入带图片的excel列表数据。 考虑到低代码平台的表头与数据的不确定性&#xff0c;技术框架上暂定使用Apache-POI。 …

java 自定义填充excel并导出

首先在resources下面放一个excel模板 1. 方法签名和请求映射 RequestMapping(value "/ExportXls") public ResponseEntity<byte[]> rwzcExportXls(HttpServletRequest request, RequestBody JSONArray jsonArray) throws IOException { RequestMapping(val…

ubuntu 开放 8080 端口快捷命令

文章目录 查看防火墙状态开放 80 端口开放 8080 端口开放 22端口开启防火墙重启防火墙**使用 xhell登录**&#xff1a; 查看防火墙状态 sudo ufw status [sudo] password for crf: Status: inactivesudo ufw enable Firewall is active and enabled on system startup sudo…

微服务实战——登录(普通登录、社交登录、SSO单点登录)

登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…

进阶功法:SQL 优化指南

目录标题 SQL 优化指南1. 插入数据优化1.1 批量插入数据1.2 手动提交事务1.3 主键顺序插入1.4 大批量插入数据步骤&#xff1a; 2. 主键优化主键设计原则拓展知识 3. ORDER BY 优化3.1 Using filesort3.2 Using index示例 3.3 ORDER BY 优化原则 4. GROUP BY 优化示例 4.1 GROU…

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…

电力设备图像分割系统源码&数据集分享

电力设备图像分割系统系统源码&#xff06;数据集分享 [yolov8-seg-efficientViT&#xff06;yolov8-seg-C2f-DCNV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI G…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…