动态规划-回文子串问题

文章目录

  • 1. 回文子串(647)
  • 2. 最长回文子串(5)
  • 3. 分割回文串 IV(1745)
  • 4. 分割回文串 II(132)
  • 5. 最长回文子序列(516)
  • 6. 让字符串成为回文串的最少插入次数(1312)


1. 回文子串(647)

题目描述:
在这里插入图片描述

状态表示:
设置一个布尔类型二维数组dp,使用dp[i][j]来表示在i和j这个闭区间内的子串是否为回文子串。
状态转移方程:
当i和j位置的元素相同时分为三种情况,第一种是i等于j,第二种就是i+1等于j,第三种是就是除了i和j位置的元素还包含中间很多元素,那么dp[i][j]=dp[i+1][j-1]。
初始化:
这里无需初始化,都赋为false即可。
填表顺序:
填表要使用到两层循环,从左至右,从上到下。
返回值:
返回值就是返回dp数组中为true的个数。
代码如下:

class Solution {public int countSubstrings(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];int ret = 0;for (int j = 0; j < n; j++) {for (int i = 0; i <= j; i++) {if (s.charAt(i) == s.charAt(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;}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

2. 最长回文子串(5)

题目描述:
在这里插入图片描述
状态表示:
这题状态表示和上一题一致。
状态转移方程:
这题状态转移方程和上一题也是一致的。
初始化:
初始化就是全是false,即不用初始化。
填表顺序:
从左至右,从上到下。
返回值:
返回dp数组中值为true的元素的i和j坐标差值为最大值的子串。
代码如下:

 class Solution {public String longestPalindrome(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];int startIndex = 0;int endIndex = 0;int max = Integer.MIN_VALUE;for (int j = 0; j < n; j++) {for (int i = 0; i <= j; i++) {if (s.charAt(i) == s.charAt(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] && j - i + 1 > max) {max = j - i + 1;startIndex = i;endIndex = j;}}}return s.substring(startIndex, endIndex + 1);}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

3. 分割回文串 IV(1745)

题目描述:
在这里插入图片描述

状态表示:
这题的状态表示与前两题一致。
状态转移方程:
与前两题一致。
初始化:
与前两题一致。
填表顺序:
与前两题一致。
返回值:
这题的返回值有点特殊,需要使用两层循环,将两层循环的下标用来分割字符串s并且判断分割好的三个子串在dp表中的值是否为true,如果都为true最终返回就是true,如果遍历完成没有一次是true,那么就返回false。
代码如下:

class Solution {public boolean checkPartitioning(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];for (int j = 0; j < n; j++) {for (int i = 0; i <= j; i++) {if (s.charAt(i) == s.charAt(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];}}}}for (int i = 0; i < n - 1; i++) {for (int j = i; j < n - 1; j++) {if (dp[0][i] && dp[i + 1][j] && dp[j + 1][n - 1]) {return true;}}}return false;}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

4. 分割回文串 II(132)

题目描述:
在这里插入图片描述

状态表示:
这里有两个动态数组,第一个sup二维数组用于辅助运算,思想和前面几题类似,就是判断i到j位置是否为一个回文子串。第二个一维的动态数组dp,dp[i]表示以i位置元素为结尾的子串可以被分割为多个回文子串的最小次数。
状态转移方程:
对于二位数组的状态转移方程我们不多赘述,前面几题用很多。对于一维数组的dp[i],如果0~i是一个回文子串,那么dp[i]的值就是0,另一种情况就是0到i不是一个回文子串,那么我们固定住i,利用一个循环来遍历i前面的元素使用j来表示,如果j到i是一个回文子串,那么更新dp[i]=Math.min(dp[i],dp[j-1]+1)。
初始化:
为了不影响运算,将dp数组全初始化为最大值。
填表顺序:
dp数组从左至右。
返回值:
因为要返回整个字符串的最小分割次数,所以直接返回dp[n-1]即可。
代码如下:

class Solution {public int minCut(String s) {int n = s.length();boolean[][] sup = new boolean[n][n];for (int j = 0; j < n; j++) {for (int i = 0; i <= j; i++) {if (s.charAt(i) == s.charAt(j)) {if (i == j) {sup[i][j] = true;} else if (i + 1 == j) {sup[i][j] = true;} else {sup[i][j] = sup[i + 1][j - 1];}}}}int[] dp = new int[n];for (int i = 0; i < n; i++) {dp[i] = Integer.MAX_VALUE;}for (int i = 0; i < n; i++) {if (sup[0][i]) {dp[i] = 0;} else {for (int j = i; j >= 1; j--) {if (sup[j][i]) {dp[i] = Math.min(dp[i], dp[j - 1] + 1);}}}}return dp[n - 1];}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

5. 最长回文子序列(516)

题目描述:
在这里插入图片描述

状态表示:
和第二题一致。
状态转移方程:
和第二题一致。
初始化:
和第二题一致。
填表顺序:
和第二题一致。
返回值:
这题和第二题就是一样的题目,只不过第二题要返回字符串,但是这里返回的只是长度。
代码如下:

class Solution {public int longestPalindromeSubseq(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];int max = 1;for (int j = 0; j < n; j++) {for (int i = 0; i <= j; i++) {if (s.charAt(i) == s.charAt(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] && j - i + 1 > max) {max = j - i + 1;}}}return max;}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

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

题目描述:
在这里插入图片描述

状态表示:
使用二位数组dp[i][j]表示在i和j区间的子串变成回文子串的最小插入次数。
状态转移方程:
分为两种情况,第一种i和j位置元素相等时,当i+1等于j时,dp[i][j]=0,当i等于j时,dp[i][j]=0,当i+1<j时,dp[i][j]=dp[i+1][j-1]。第二种情况当i和j位置元素不相等时,需要插入元素所以dp[i][j]=Math.min(dp[i+1][j],dp[i][j-1])+1;
初始化:
无需初始化。
填表顺序:
从下到上,从左至右。
返回值:
返回0到n-1的原字符串的最小分割次数即dp[0][n-1]。
代码如下:

class Solution {public int minInsertions(String s) {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.charAt(i) == s.charAt(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];}
}

题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)

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

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

相关文章

文心一言+Midjourny中文站

目录 你用过最好用的AI工具有哪些&#xff1f; 文心一言 Midjourney中文站 #你用过最好用的AI工具有哪些&#xff1f;# 你用过最好用的AI工具有哪些&#xff1f; 简介&#xff1a;目前市面上有很多新的AI工具&#xff1a;文心、天工、Midjourney等等&#xff0c;当然也有很大…

低代码工业组态数字孪生平台

2024 两会热词「新质生产力」凭借其主要特征——高科技、高效能及高质量&#xff0c;引发各界关注。在探索构建新质生产力的重要议题中&#xff0c;数据要素被视为土地、劳动力、资本和技术之后的第五大生产要素。数据要素赋能新质生产力发展主要体现为&#xff1a;生产力由生产…

万兴PDF专家 PDFelement Pro v10.3.8 破姐版!

&#x1f9d1;‍&#x1f4bb;万兴PDF专家 PDFelement Pro v10.3.8 破姐版 (https://docs.qq.com/sheet/DRVVxTHJ3RXJFVHVr)

带你学C语言:结构体及其内存

目录 &#x1f37a;0.前言 ✍1.结构体 &#x1f440;1.1为何结构体 &#x1f440;1.2结构体怎么声明 &#x1f440;1.3结构体怎么创建 &#x1f440;1.4结构体初始化与访问 ✋1.5匿名结构体问题 &#x1f646;1.6结构体的自我调用 &#x1f69d; 2.结构体的内存对齐 &a…

Midjourney之绘画背景的选择

hello 小伙伴们&#xff0c;我是你们的老朋友——树下&#xff0c;今天分享Midjourney提示词中绘画背景的选择&#xff0c;话不多说&#xff0c;直接开始~ 对于背景的选择&#xff0c;Midjourney中主要体现在年代和所处的环境对绘画产生不同的影响 科技的发展&#xff0c;我们…

质因数分解(cpp实现)--一种快速求得一个数有多少个因子的黑魔法

前言 最近机试没少吃不会质因数分解的亏&#xff0c;用传统的求得因子个数只能过一点点…(ex, 20%) 质因数分解后&#xff0c;可以将因子问题转化为 集合的组合问题&#xff0c;因此会很快&#xff0c;目测是 l o g n log n logn (n是该整数的值)。 传统解法 假设输入整数的…

小区服务|基于SprinBoot+vue的小区服务管理系统(源码+数据库+文档)

目录 基于SprinBootvue的小区服务管理系统 一、前言 二、系统设计 三、系统功能设计 1管理员登录 2 客服聊天管理、反馈管理管理 3 公告信息管理 4公告类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博…

Windows 10 使用 Vagrant 快速创建虚拟机

一、下载 VirtualBox 官网地址&#xff1a;Oracle VM VirtualBox 阿里云盘&#xff1a;阿里云盘分享 二、安装 VirtualBox 安装软件前请先确认 CPU 是否开启了虚拟化&#xff0c;要求开启 2.1、双击运行可执行文件后点击下一步 2.2、选择安装路径&#xff0c;为了避免中文乱码…

STM32 看门狗WDG

一、看门狗&#xff08;Watchdog&#xff09; 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系统的可靠…

基于Spring Boot的校园闲置物品交易网站设计与实现

基于Spring Boot的校园闲置物品交易网站设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 系统功能界面图&#xff0c;在系统首页可以查看…

【Java】 对象的比较【比较器】

登神长阶 第七阶 Java对象的比较 &#x1f3b7;一.Java对象的比较 &#x1fa97;1.基于引用的比较 基于引用的比较在Java中使用运算符进行。它主要检查两个对象是否引用内存中的相同位置。以下是基于引用的比较的详细介绍&#xff1a; 使用运算符&#xff1a; 运算符用于比…

3-4STM32C8T6按键控制LED开与关

实物接线如下&#xff1a; 为了代码的简洁性&#xff0c;这里需要对LED与KEY进行封装如下&#xff1a; #include "stm32f10x.h" // Device headervoid LED_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GP…