【动态规划五】回文串问题

目录

leetcode题目

一、回文子串

二、最长回文子串

三、分割回文串 IV

四、分割回文串 II

五、最长回文子序列

六、让字符串成为回文串的最少插入次数


leetcode题目

一、回文子串

647. 回文子串 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/palindromic-substrings/1.题目解析

返回给定字符串中所有回文子串的个数

2.算法分析

1.状态表示

如果是暴力解法,只需要先固定下标i, 然后j从i的位置开始往后一路枚举即可,下一次i++, j无需回到0号下标,因为[i, j]与[j, i]本质是同一个子串,j直接从i位置开始枚举即可, 因此我们就把状态表示定义成二维的~

dp[i][j]: s字符串中位于区间 [i, j] 的字符串, 是否是回文串 (隐含条件: i <= j)

2.状态转移方程

3.初始化

初始化的目的是 保证填表时不越界 + 后续填表是正确的

4.填表顺序

填dp[i][j]时,需要dp[i+1][j-1]的值,因此需要从下往上填每一行即可

5.返回值

返回dp表中值为true的个数即可

3.算法代码

class Solution {
public:int countSubstrings(string s) {//1.创建dp表int n = s.size();vector<vector<bool>> dp(n, vector<bool>(n, false));//2.填表+返回值int sum = 0;for(int i = n-1; i >= 0; i--) //从下往上填表{for(int j = i; j < n; j++){if(s[i] == s[j])dp[i][j] = i + 1 < j ? dp[i+1][j-1] : true;if(dp[i][j]) sum++; }}return sum;}
};

二、最长回文子串

5. 最长回文子串 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/longest-palindromic-substring/1.题目解析

返回给定字符串中的最长回文子串

2.算法分析

求最长回文子串之前,先要知道哪些字符串是回文串,而题目一通过dp表,记录了[i, j]子串是否是回文串,根据dp表的值即可得到想要的结果

3.算法代码

class Solution {
public:string longestPalindrome(string s) {//1.创建dp表int n = s.size();vector<vector<bool>> dp(n, vector<bool>(n, false));//2.填表+返回值int begin = 0, len = 0;for(int i = n-1; i >= 0; i--) //从下往上填表{for(int j = i; j < n; j++){if(s[i] == s[j])dp[i][j] = i + 1 < j ? dp[i+1][j-1] : true;//更新结果if(dp[i][j] && len < j - i + 1) {len = j - i + 1;begin = i;}}}return s.substr(begin, len);}
};

三、分割回文串 IV

1745. 分割回文串 IV - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/palindrome-partitioning-iv/1.题目解析

判断给定的字符串是否能够分割成三个回文字符串, 返回true/false

2.算法分析

本题的关键就是看给定字符串能否被分割成三个回文子串, 也就是判断[0, i-1], [i, j], [j+1, n-1]这三个区间的字符串是否是回文子串,而题目一中我们用动态规划做到了使用dp表保存所有的子串是否是回文信息,因此用o(1)的时间复杂度判断即可

3.算法代码

class Solution {
public:bool checkPartitioning(string s) {//1.创建dp表int n = s.size();vector<vector<bool>> dp(n, vector<bool>(n, false));//2.填表for(int i = n-1; i >= 0; i--)for(int j = i; j < n; j++)if(s[i] == s[j])dp[i][j] = i + 1 < j ? dp[i+1][j-1] : true;  //3.返回值for(int i = 1; i < n - 1; 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;}
};

四、分割回文串 II

132. 分割回文串 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/palindrome-partitioning-ii/本题与 139. 单词拆分 - 力扣(LeetCode) 这道题目非常类似,大家可以对比一下两道题的做法

【动态规划三】子数组系列-CSDN博客文章浏览阅读803次,点赞20次,收藏21次。f[i]:以 i 位置为结尾的所有子数组中,最后呈现 "上升" 状态下的最长的湍流子数组的长度。g[i]:以 i 位置为结尾的所有子数组中,最后呈现 "下降" 状态下的最长的湍流子数组的长度。数组中相邻元素对之间的大小关系相反,这就是湍流数组,题目要求返回数组中最长的湍流子数组的长度。将dp表里面所有的值都初始化成1, 因此dp[i] += dp[i-1] 即可。dp[i]: [0, i]区间内的字符串, 能否被字典中的单词拼接而成。dp[i] 表示 以 i 位置元素为结尾的所有子数组的最大和。https://blog.csdn.net/m0_74126249/article/details/138501298?spm=1001.2014.3001.55011.题目解析

给定字符串s,将s分割,使得每个部分都是回文子串,求最少的分割次数

2.算法分析

1.状态表示

dp[i] 表示 [0, i] 区间上的字符串, 分割成回文串的最少分割次数

2.状态转移方程

而本题目要频繁的用到判断一个字符串是否是回文,因此用到题目一的做法,把所有子串是否是回文的信息,保存在dp表中

3.初始化

j > 0, 所以填表一定不会越界; 但是 dp[i] = min(dp[j-1] + 1, dp[i]), 所以我们把dp[i]都初始化成无穷大,不会干扰结果

4.填表顺序

从左往右

5.返回值

dp[n-1]

3.算法代码

class Solution {
public:int minCut(string s) {//1.预处理isPal表int n = s.size();vector<vector<bool>> isPal(n, vector<bool>(n, false));for(int i = n-1; i >= 0; i--)for(int j = i; j < n; j++)if(s[i] == s[j])isPal[i][j] = i + 1 < j ? isPal[i+1][j-1] : true;  //2.创建dp表 + 初始化vector<int> dp(n, INT_MAX);//3.填表for(int i = 0; i < n; i++){if(isPal[0][i])dp[i] = 0;else{for(int j = 0; j <= i; j++)if(isPal[j][i]) dp[i] = min(dp[i], dp[j-1]+1);}}//4.返回值return dp[n-1];}
};

五、最长回文子序列

516. 最长回文子序列 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/longest-palindromic-subsequence/1.题目解析

与题目二的区别是子序列不一定连续,本题求的是原字符串中最长的回文子序列

2.算法分析

1.状态表示

dp[i][j]:[i, j]内的所有子序列中,最长的回文子序列的长度(隐含条件: i <= j)

2.状态转移方程

2.1  i == j时, s[i] 必然 == s[j], 因此我们可以在刚进入第一层for循环时就将dp[i][i]填成1

2.2 上面的s[i] == s[j]中的 i + 1 == j 的情况合并到 i + 1 < j 的情况中,因为当i+1 == j 时,  dp[i+1][j]都是下三角元素,默认是0, 0 + 2还是2, 不影响结果的正确性

3.初始化

无需初始化

4.填表

从下往上填表,每一行从左往右填

5.返回值

dp[0, n-1]

3.算法代码

class Solution {
public:int longestPalindromeSubseq(string s) {//1.创建dp表int n = s.size();vector<vector<int>> dp(n, vector<int>(n));//2.填表for(int i = n - 1; i >= 0; i--){dp[i][i] = 1; //对应s[i] == s[j] && i == j 的情况for(int j = i + 1; j < n; j++){if(s[i] == s[j])dp[i][j] = dp[i+1][j-1] + 2;elsedp[i][j] = max(dp[i+1][j], dp[i][j-1]);}}//3.返回值return dp[0][n-1];}
};

六、让字符串成为回文串的最少插入次数

1312. 让字符串成为回文串的最少插入次数 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/minimum-insertion-steps-to-make-a-string-palindrome/1.题目解析

给定字符串,可以在任意位置插入任意字符使其变为回文串,求最少的插入次数

2.算法分析

1.状态表示

dp[i][j]:s里面,[i, j]区间上的字符串, 使它成为回文串的最少插入次数

2.状态转移方程

s[i] == s[j]时,i + 1 == j 的情况可以合并到 i + 1 < j的情况中,因为i + 1 > j 时用到的dp[i+1][j-1]本质是下三角元素,直接等于0,不影响结果的正确性

3.初始化

无需初始化

4.填表顺序

从下往上填表,每一行从左往右

5.返回值

dp[0][n-1]

3.算法代码

class Solution
{
public:int minInsertions(string s) {//1.创建dp表int n = s.size();vector<vector<int>> dp(n, vector<int>(n));//2.填表for(int i = n - 1; i >= 0; i--)for(int j = i + 1; j < n; j++)if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1];else dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1; //3.返回值return dp[0][n-1];}
};

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

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

相关文章

5.15_操作符详解

1、操作符分类&#xff1a; 算术操作符 - * / % 移位操作符 << >> 位操作符 & | ^ 赋值操作符 - ...... 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用、函数调用和结构成员 2、算术操作符 - * / …

将TailwindCSS默认单位rem转换为px

前言&#xff1a; 我这里需要将 默认的rem 转换为 px 原因是要使用 postcss-px-to-viewport 插件做移动端适配。 在tailwind.config.js文件中进行配置&#xff1a; 注意&#xff1a;这里 padding&#xff08;内边距&#xff09;、spacing&#xff08;外边距&#xff09;、width…

Spacy的安装与使用教程

官网安装指导教程 https://spacy.io/usage 安装指令 需要根据自己系统的cuda版本选择 nvcc -V pip install -U pip setuptools wheel pip install -U spacy[cuda12x] python -m spacy download zh_core_web_sm python -m spacy download en_core_web_sm

【Linux】系统登录,调用shell,shell配置文件,shell命令,特殊符号,shell快捷键,Linux运行级别,解决无限登录问题,修改提示符

目录 Linux系统的登录方式 以及 调用shell Linux shell 以及 shell配置文件 shell 命令 shell 特殊符号 shell 快捷键 Linux操作系统运行级别 单用户模式下解决无限登录问题 centos7修改命令行提示符 PS1 补充、centos7没有滚动条 Linux系统的登录方式 以及 调用shell…

vue3.0+antdv的admin管理系统vue-admin-beautiful推荐

前言 几年前&#xff0c;笔者自学了vue这一优秀的前端框架&#xff0c;但苦于没项目练手&#xff0c;无意间发现了vue-admin-beautiful这一优秀的前端集成框架。当时就使用它做了一很有意思的小项目---终端监控云平台&#xff0c;实现了前端和后台的整体功能。整体方案介绍参见…

查询新加 字段不返回数据要看 有没有 AllInfoResultMap 有要再里面加字段

查询新加 字段不返回数据要看 有没有 AllInfoResultMap 有要再里面加字段

HTTP客户端手动解析响应体数据

服务端 package mainimport ("easyGo/person""encoding/json""net/http" )func main() {http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {p : &person.Person{Name: "jackie",Age: 30,T: pe…

操作系统-单片机进程状态问题(三态模型问题)

例题&#xff1a;在单处理机计算机系统中有1台打印机、1台扫描仪&#xff0c;系统采用先来先服务调度算法。假设系统中有进程P1、P2、P3、P4&#xff0c;其中P1为运行状态&#xff0c;P2为就绪状态&#xff0c;P3等待打印机&#xff0c;P4等待扫描仪。此时&#xff0c;若P1释放…

Java并发编程VarHandle类

Java 的 VarHandle 是在 Java 9 中引入的一种新机制&#xff0c;旨在提供对变量&#xff08;包括对象字段、数组元素和静态变量&#xff09;的可变引用和非阻塞操作。VarHandle 主要用于并发编程&#xff0c;提供了一种更灵活且性能更高的方式来进行变量访问和更新操作&#xf…

es6新语法和ajax和json

es6新语法 1.定义变量&#xff1a;let 2.定义常量&#xff1a;const <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

用友GRP-U8 userInfoWeb SQL注入致RCE漏洞复现 (XVE-2024-10539)

0x01 产品简介 用友GRP-U8R10行政事业内控管理软件是用友公司专注于国家电子政务事业,基于云计算技术所推出的新一代产品,是我国行政事业财务领域最专业的政府财务管理软件。 0x02 漏洞概述 用友GRP-U8R10行政事业内控管理软件 userInfoWeb接口处存在SQL注入漏洞,未授权的…

ADS使用记录之使用RFPro进行版图联合仿真-加入集总元器件

ADS使用记录之使用RFPro进行版图联合仿真-加入集总元器件 ADS使用记录之使用RFPro进行版图联合仿真中已经简单介绍了使用RFPro对版图就行仿真的方法。但是&#xff0c;如果版图中含有一些非微带的结构&#xff0c;比如说电感、电容、晶体管呢&#xff0c;在此举例解释一下。 …

leetcode61-Rotate List

题目 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3] 分析 这道题目用快慢指针即可解&#xff0c;先快指针往前走k个位置&#x…

MyBatis中关于resultType和resultMap的区别

在MyBatis中&#xff0c;resultType和resultMap都是用于处理查询结果的&#xff0c;但它们之间存在一些关键的区别。 映射方式&#xff1a; resultType&#xff1a;直接表示返回类型&#xff0c;它通常对应着Java模型对象&#xff08;如POJO&#xff09;中的实体。当查询出来的…

百度:文心大模型日均处理Tokens文本已达2490亿

今日&#xff0c;记者从百度获悉&#xff0c;文心大模型日均处理Tokens文本已达2490亿。百度表示&#xff0c;这几天&#xff0c;国内外多家厂商相继发布大模型最新进展和相关应用&#xff0c;百度很高兴地看到&#xff0c;“闭源大模型公有云”已经成为全球AI市场的主流趋势。…

Django信号与扩展:深入理解与实践

title: Django信号与扩展&#xff1a;深入理解与实践 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 后端开发 tags: Django信号松耦合观察者扩展安全性能 第一部分&#xff1a;Django信号基础 Django信号概述 一. Django信号的定义与作用 Django信…

NAT技术总结与双向NAT配置案例

NAT的转换方式&#xff1a; 1.静态转换&#xff1a;固定的一对一IP地址映射。 interface GigabitEthernet0/0/1 ip address 122.1.2.24 nat static global 122.1.2.1 inside 192.168.1.1 #在路由器出接口 公网地址 私网地址。 2.动态转换&#xff1a;Basic NAT nat address-gr…

有多少小于当前数字的数字

链接&#xff1a;https://leetcode.cn/problems/how-many-numbers-are-smaller-than-the-current-number/description/ 思路&#xff1a; 最简单的思路来说&#xff0c;就是双重for循环进行遍历&#xff0c;来判断个数&#xff0c; 优化思路&#xff0c;其中一个思路就是递推 …

day3 leetcode20 有效的括号

有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相…

C语言操作符详解(一)

算术操作符&#xff1a; 算术操作符有&#xff1a;加法 减法- 乘法* 除法/ 取余% 算术操作符该注意的点&#xff1a; 1.除了%操作符之外&#xff0c;其他的操作符都可以作用于整数和浮点数。 2.对于/操作符来说&#xff0c;两个数都是整数的话&#xff0c;结果只能是…