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

目录

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;
                else
                    dp[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];
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux网络编程——HTTP协议的理解与运用

目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道&#xff0c;协议就是一种约定&#xff0c;客户端与服务端统一的用这种约定进行传输数据。我们…

deepin V23 RC 正式发布!

deepin 是一款基于 Linux 的开源桌面操作系统&#xff0c;就在今天&#xff0c;deepin V23 RC 来了&#xff0c;欢迎体验与反馈&#xff01; 感谢每一位 deepiner 提供想法与建议&#xff0c;让我们一起为打造美观易用、安全可靠的开源操作系统而努力&#xff01; 重要提示&a…

用docker命令行操作远程的Dockerd daemon服务

本地安装 Dockerd 服务太耗本机磁盘空间了&#xff0c;共用已有的Dockerd服务能够节省一部分空间 修改 Dockerd 服务启动文件&#xff0c;增加TCP监听方式 Dockerd 服务默认监听方式为 Unix Domain Socket &#xff0c;只允许本机连接&#xff0c;想要能够远程连接&#xff0…

一文说通用户故事点数是什么?

一文说通用户故事点数是什么&#xff1f; 第26期&#xff1a;一文说通用户故事点数是什么&#xff1f; 用户故事点数是一种采用相对估算法进行估算的一种工具&#xff0c;一般采用斐波那契数列表征用户故事里说的大小&#xff0c;采用0 1 2 3 5 8 13这样的一些数字来表征用户…

使用人人开源renren-fast快捷搭建后台管理系统

https://gitee.com/renrenio/renren-fast https://gitee.com/renrenio/renren-fast 初始化项目数据库 导入项目运行 期间遇到的坑 024-04-25 01:30:27.638 ERROR 25228 --- [ main] com.alibaba.druid.pool.DruidDataSource : init datasource error, url: jdbc:…

Postman基础功能-接口返回值获取

大家好&#xff0c;之前给大家分享关于Postman的接口关联&#xff0c;我们平时在做接口测试时&#xff0c;请求接口返回的数据都是很复杂的 JSON 数据&#xff0c;有着多层嵌套&#xff0c;这样的数据层级在 Postman 中要怎么获取呢&#xff1f; 接下来给大家展示几个获取 JSO…

计算机系列之排序算法

20、排序算法 1、直接插入排序&#xff08;这里以从小到大排序为例&#xff09; ◆要注意的是&#xff0c;前提条件是前i-1个元素是有序的&#xff0c;第i个元素依次从第i-1个元素往前比较&#xff0c;直到找到一个比第i个元素值小的元素&#xff0c;而后插入&#xff0c;插入…

免费SSL证书:适合你的网站吗?

随着互联网的发展&#xff0c;安全性已经成为了网站运营不可或缺的一部分。而SSL证书作为保障网站数据传输安全的重要手段&#xff0c;被越来越多的网站所采纳。然而&#xff0c;对于很多小型网站或者个人博客来说&#xff0c;付费购买SSL证书可能会带来一定的经济压力。因此&a…

Linux---编辑器vim的认识与简单配置

前言 我们在自己的电脑上所用的编译软件&#xff0c;就拿vs2022来说&#xff0c;我们可以在上面写C/C语言、python、甚至java也可以在上面进行编译&#xff0c;这种既可以用来编辑、运行编译&#xff0c;又可以支持很多种语言的编译器是一种集成式开发环境&#xff0c;集众多于…

UIKit之图片浏览器

功能需求 实现一个图片浏览器&#xff0c;点击左右按钮可以切换背景图&#xff0c;且更新背景图对应的索引页和图片描述内容。 分析&#xff1a; 实现一个UIView的子类即可&#xff0c;该子类包含多个按钮。 实现步骤&#xff1a; 使用OC语言&#xff0c;故创建cocoa Touch类…

解决kali Linux安装后如何将语言修改为中文

开启虚拟机 用root用户进入终端 进入终端执行dpkg-reconfigure locales命令 选择en_US.UTF-8 UTF-8选项&#xff0c;按空格键将其取消。 选择zh_CN.UTF-8 UTP-8&#xff0c;按空格选择&#xff0c;按tab键选择ok。 选择zh_CN.UTF-8字符编码&#xff0c;按tab键选择ok&#xff0…

【JAVA】嵌入式软件工程师-2025校招必备-详细整理

一、Java 基础 1.JDK 和 JRE 有什么区别&#xff1f; jdk&#xff1a;java development kit jre&#xff1a;java runtime Environment jdk是面向开发人员的&#xff0c;是开发工具包&#xff0c;包括开发人员需要用到的一些类。 jre是java运行时环境&#xff0c;包括java虚拟机…

IDEA的妙用

IDEA 安装破解 复制JetbrainsIdesCrack-4.2.jar到安装目录下 修改安装目录下的bin目录的idea64.exe.vmoptions&#xff1a; 最后一行添加&#xff1a;-javaagent:E:\develop\JetBrains\IntelliJ IDEA 2018.3.5\bin\JetbrainsIdesCrack-4.2.jar(注意&#xff1a;使用自己的路…

(2)双指针练习:复写零

复写零 题目链接&#xff1a;1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入…

WebSocket or SSE?即时通讯的应用策略【送源码】

最近在研究H5推送&#xff0c;发现除了我们常用的WebSocket以外&#xff0c;其实还有一种协议也能实现H5推送&#xff0c;那就是SSE协议。 而且&#xff0c;当前主流的大模型平台&#xff0c;比如ChatGPT、通义千问、文心一言&#xff0c;对话时采用的就是SSE。 什么是SSE协议…

基于HTML5和CSS3搭建一个Web网页(一)

倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 网页描述 创建一个包含导航栏、主内容区域和页脚的响应式网页。 需求: 导航栏: 在页面顶部创建一个导航栏&#xff0c;包含首页、关于我们、服务和联系我们等链接。 设置导航栏样式&#xff0c;包括字体、颜色和背景颜…

识物扫一扫识别植物怎么做?6个软件教你轻松识别植物

识物扫一扫识别植物怎么做&#xff1f;6个软件教你轻松识别植物 识别植物可以通过专门的植物识别应用来实现。以下是六款可以帮助您轻松识别植物的软件&#xff1a; 1.一键识别王&#xff1a;这款软件有着强大的植物识别服务&#xff0c;用户可以通过拍照或上传图片来识别植物…

算法学习笔记(5.0)-基于比较的高效排序算法-归并排序

##时间复杂度O(nlogn) 目录 ##时间复杂度O(nlogn) ##递归实现归并排序 ##原理 ##图例 ##代码实现 ##非递归实现归并排序 ##释 #代码实现 ##递归实现归并排序 ##原理 是一种基于分治策略的基础排序算法。 1.划分阶段&#xff1a;通过不断递归地将数组从中点处分开&…

迷宫游戏(c++)

我们来玩一个迷宫游戏&#xff0c;尝试走一下面的迷宫。 迷宫游戏 我们用一个二维的字符数组来表示前面画出的迷宫&#xff1a; S**. .... ***T 其中字符S表示起点&#xff0c;字符T表示终点&#xff0c;字符*表示墙壁&#xff0c;字符.表示平地。你需要从S出发走到T&#xf…

【全开源】JAVA共享自习室共享学习室无人系统支持微信小程序+微信公众号+H5

开启智能学习新时代 随着社会的快速发展&#xff0c;人们对于学习环境的需求也日益增加。为满足这一需求&#xff0c;我们推出了“共享自习室系统源码”&#xff0c;旨在通过智能化的管理方式&#xff0c;打造高效、便捷、舒适的共享学习空间。 核心功能 自习室预约&#xf…