动态规划 之 回文子串 算法专题

一. 回文子串

回文子串

  1. 状态表示
    将所有子串是否是回文串的信息, 保存在dp表中
    dp[i][j] 表示 从i到j的子串是否是回文串
  2. 状态转移方程
    如果s[i] != s[j] 一定不是回文子串
    如果s[i] == s[j] 分三种情况:
    1.i == j 指同一个字符, 一定是回文串 true
    2.i + 1 == j 两个字符, 一定是回文串 true
    3.dp[i][j] = dp[i + 1][j - 1]
  3. 初始化
    无需初始化 上面的条件已经帮我们完成
  4. 填表顺序
    从下往上, 从左往右
  5. 返回值
    返回true的个数
class Solution {public int countSubstrings(String s) {int n = s.length();char[] ss = s.toCharArray();boolean[][] dp = new boolean[n][n];int ret = 0;for (int i = n - 1; i >= 0; i--) {for (int j = i; j < n; j++) {if (ss[i] == ss[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;}
}

二. 最长回文子串

最长回文子串

class Solution {public String longestPalindrome(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];int p = 0, len = 0;for(int i = n; i >= 0; i--){for(int j = i; j < n; j++){if(s.charAt(i) == s.charAt(j)){if(i == j || i + 1 == j) dp[i][j] = true;else dp[i][j] = dp[i + 1][j - 1]; }if(dp[i][j] && j - i + 1 > len){p = i; len = j - i + 1;}}}return s.substring(p, p + len);}
}

三. 回文串分割IV

回文串分割
用i j 表示中间子串的开始和结束位置
字符串被分成dp[0][i - 1] && dp[i][j] && dp[j + 1][n - 1] 三部分

class Solution {public boolean checkPartitioning(String s) {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.charAt(i) == s.charAt(j)){if(i == j || i + 1 == j) dp[i][j] = true;else dp[i][j] = dp[i + 1][j - 1];}}}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

  1. 状态表示
    dp[i][j] 表示 (0, i)字符串中, 需要分割的最小次数
  2. 状态转移方程
    1.(0, i)是回文串, dp[i] = 0;
    2.(0, i)不是回文串, 分成两种情况
    定义j, 0 < j <= i
    如果(j, i)是回文串, dp[i] = dp[i - 1] + 1
    如果(j, i)不是回文串, 判断下一个位置
  • dp[i] = min(dp[i - 1] + 1)
  1. 初始化
    dp每个元素初始化为最大值, 防止干扰结果
  2. 填表顺序
    从左往右
  3. 返回值
    dp[n - 1]
class Solution {public int minCut(String s) {int n = s.length();boolean[][] tmp = new boolean[n][n];int[] dp = new int[n];Arrays.fill(dp, Integer.MAX_VALUE);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 || i + 1 == j)tmp[i][j] = true;elsetmp[i][j] = tmp[i + 1][j - 1];}}}for (int i = 0; i < n; i++) {if (tmp[0][i])dp[i] = 0;else {for (int j = 1; j <= i; j++) {if (tmp[j][i])dp[i] = Math.min(dp[j - 1] + 1, dp[i]);}}}return dp[n - 1];}
}

五. 最长回文子序列

最长回文子序列

  1. 状态表示
    dp[i][j] 表示 (i, j)字符串中, 最长回文子序列

  2. 状态转移方程
    如果s[i] == s[j] :
    1.i == j , 最长为1
    2.i +1 = j, 最长为2
    3.其余情况, 要找i + 1 和 j - 1 的最长回文子序列 + 2
    如果s[i] != s[j] : 说明不是ij都选, 只选择其中一个, 求最大值
    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])

  3. 初始化
    无需初始化, 不会越界

  4. 填表顺序
    从左往右, 从下往上

  5. 返回值
    dp[0][n - 1]

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

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

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

  1. 状态表示
    dp[i][j] 表示 (i, j)字符串中, 让字符串成为回文串的最少插入次数
  2. 状态转移方程
    如果s[i] == s[j] :
    1.i == j , 最少次数为0
    2.i +1 = j, 最少次数为0
    3.其余情况, 要找i + 1 和 j - 1 的最少次数, 为dp[i + 1][j - 1]
    如果s[i] != s[j]
    可以在 i 之前插入s[j], dp[i][j] = dp[i][j - 1] + 1
    可以在 j 之后插入s[i], dp[i][j] = dp[i + 1][j] + 1
  • dp[i][j] = min(dp[i][j - 1] + 1, dp[i + 1][j] + 1)
  1. 初始化
    无需初始化, 不会越界
  2. 填表顺序
    从左往右, 从下往上
  3. 返回值
    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 + 1; j < n; j++) {if (s.charAt(i) == s.charAt(j)) {if (i + 1 < j) {dp[i][j] = dp[i + 1][j - 1];}} else {dp[i][j] = Math.min(dp[i][j - 1], dp[i + 1][j]) + 1;}}}return dp[0][n - 1];}
}

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

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

相关文章

解读缓存问题的技术旅程

目录 前言1. 问题的突发与初步猜测2. 缓存的“隐身术”3. 缓存策略的深层优化4. 反思与感悟结语 前言 那是一个普通的工作日&#xff0c;团队例行的早会刚刚结束&#xff0c;我正准备继续优化手头的模块时&#xff0c;突然收到了用户反馈。反馈的内容是部分数据显示异常&#…

WPS 加载项开发说明wpsjs

wpsjs几个常用的CMD命令&#xff1a; 1.打开cmd输入命令测试版本号 npm -v 2.首次安装nodejs&#xff0c;npm默认国外镜像&#xff0c;包下载较慢时&#xff0c;可切换到国内镜像 //下载速度较慢时可切换国内镜像 npm config set registry https://registry.npmmirror.com …

【深度学习】循环神经网络及文本生成模型构建

循环神经网络 词嵌入层 ​ 词嵌入层的作用就是将文本转换为向量。 ​ 词嵌入层首先会根据输入的词的数量构建一个词向量矩阵&#xff0c;例如: 我们有 100 个词&#xff0c;每个词希望转换成 128 维度的向量&#xff0c;那么构建的矩阵形状即为: 100*128&#xff0c;输入的每…

论文阅读:Uni-ISP Unifying the Learning of ISPs from Multiple Cameras

这是 ECCV 2024 的一篇文章&#xff0c;文章作者想建立一个统一的 ISP 模型&#xff0c;以实现在不同手机之间的自由切换。文章作者是香港中文大学的 xue tianfan 和 Gu jinwei 老师。 Abstract 现代端到端图像信号处理器&#xff08;ISPs&#xff09;能够学习从 RAW/XYZ 数据…

ROS2指令总结(跟随古月居教程学习)

​ 博主跟随古月居博客进行ROS2学习&#xff0c;对ROS2相关指令进行了总结&#xff0c;方便学习和回顾。 古月居ROS2博文链接&#xff1a;https://book.guyuehome.com/ 本文会持续进行更新&#xff0c;觉得有帮助的朋友可以点赞收藏。 1. ROS2安装命令 $ sudo apt update &am…

Qt不同类之间参数的传递

一、信号槽方式 1: 在需要发送信号的子类增加一个信号函数 void set_send(double lonx, double laty);sub.h sub.cpp emit set_send(lonx,laty);2: 在需要接收信号的类增加一个槽函数 main.h void set_rece(double lonx, double laty);main.cpp 1&#xff09;引入子类头文…

labview记录系统所用月数和天数

在做项目时会遇到采集系统的记录&#xff0c;比如一个项目测试要跑很久这个时候就需要在软件系统上显示项目运行了多少天&#xff0c;从开始测试开始一共用了多少年多少月。 年的话还好计算只需要把年份减掉就可以了&#xff0c;相比之下月份和天数就比较难确定&#xff0c;一…

机器翻译基础与模型 之一: 基于RNN的模型

一、机器翻译发展历程 基于规则的-->基于实例的-->基于统计方法的-->基于神经网络的 传统统计机器翻译把词序列看作离散空间里的由多个特征函数描述的点&#xff0c;类似 于 n-gram 语言模型&#xff0c;这类模型对数据稀疏问题非常敏感。神经机器翻译把文字序列表示…

WPF Prism框架

一、关于Prism框架 Prism.Core:【Prism.dll】实现MVVM的核心功能&#xff0c;属于一个与平台无关的项目 Prism.Wpf&#xff1a;【Prism.Wpf】包含了DialogService,Region,Module,Navigation,其他的一些WPF的功能 Prism.Unity:【Prism.Unity.Wpf】,IOC容器 Prism.Unity>Pr…

STM32F103系统时钟配置

时钟是单片机运行的基础&#xff0c;时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏&#xff0c;决定CPU速率&#xff0c;像人的心跳一样 只有有了心跳&#xff0c;人才能做其他的事情&#xff0c;而单片机有了时钟&#xff0c;才能够运行执行指令&#x…

2024年 Web3开发学习路线全指南

Web3是一个包含了很多领域的概念&#xff0c;不讨论币圈和链圈的划分&#xff0c;Web3包括有Defi、NFT、Game等基于区块链的Dapp应用的开发&#xff1b;也有VR、AR等追求视觉沉浸感的XR相关领域的开发&#xff1b;还有基于区块链底层架构或者协议的开发。 这篇文章给出的学习路…

CTF--php伪协议结合Base64绕过

Base64绕过 在ctf中&#xff0c;base64是比较常见的编码方式&#xff0c;在做题的时候发现自己对于base64的编码和解码规则不是很了解&#xff0c;并且恰好碰到了类似的题目&#xff0c;在翻阅了大佬的文章后记录一下&#xff0c;对于base64编码的学习和一个工具 base64编码是…

Linux 命令之 tar

文章目录 1 tar 命令介绍2 压缩与解压缩2.1 压缩2.2 解压 4 高级用法4.1 排除目录4.2 显示进度4.2.1 脚本解压缩4.2.2 命令解压缩4.2.3 压缩进度 1 tar 命令介绍 常见的压缩包有 .tar.gz、.tar.xz、.tar.bz2&#xff0c;以及 .rar、.zip、.7z 等压缩包。 常见的 tar 选项&#…

Jenkins修改LOGO

重启看的LOGO和登录页面左上角的LOGO 进入LOGO存在的目录 [roottest-server01 svgs]# pwd /opt/jenkins_data/war/images/svgs [roottest-server01 svgs]# ll logo.svg -rw-r--r-- 1 jenkins jenkins 29819 Oct 21 10:58 logo.svg #jenkins_data目录是我挂载到了/opt目录&…

【大模型】LLaMA: Open and Efficient Foundation Language Models

链接&#xff1a;https://arxiv.org/pdf/2302.13971 论文&#xff1a;LLaMA: Open and Efficient Foundation Language Models Introduction 规模和效果 7B to 65B&#xff0c;LLaMA-13B 超过 GPT-3 (175B)Motivation 如何最好地缩放特定训练计算预算的数据集和模型大小&…

vue添加LCD字体(液晶字体)数字美化,前端如何引用LCD字体液晶字体,如何转换?@font-face 如何使用?

文章目录 一、效果二、下载字体格式【[https://www.dafont.com/theme.php?cat302&text0123456789](https://www.dafont.com/theme.php?cat302&text0123456789)】三、下载后&#xff0c;解压后都是.ttf文件&#xff0c;在【[https://www.fontsquirrel.com/tools/webfo…

【大数据学习 | Spark】关于distinct算子

只有shuffle类的算子能够修改分区数量&#xff0c;这些算子不仅仅存在自己的功能&#xff0c;比如分组算子groupBy&#xff0c;它的功能是分组但是却可以修改分区。 而这里我们要讲的distinct算子也是一个shuffle类的算子。即可以修改分区。 scala> val arr Array(1,1,2,…

Qt桌面应用开发 第五天(常用控件 自定义控件)

目录 1.QPushButton和ToolButton 1.1QPushButton 1.2ToolButton 2.RadioButton和CheckBox 2.1RadioButton单选按钮 2.2CheckBox多选按钮 3.ListWidget 4.TreeWidget控件 5.TableWidget控件 6.Containers控件 6.1QScrollArea 6.2QToolBox 6.3QTabWidget 6.4QStacke…

Excel - VLOOKUP函数将指定列替换为字典值

背景&#xff1a;在根据各种复杂的口径导出报表数据时&#xff0c;因为关联的表较多、数据量较大&#xff0c;一行数据往往会存在三个以上的字典数据。 为了保证导出数据的效率&#xff0c;博主选择了导出字典code值后&#xff0c;在Excel中处理匹配字典值。在查询百度之后&am…

ctfshow-web入门-SSRF(web351-web360)

目录 1、web351 2、web352 3、web353 4、web354 5、web355 6、web356 7、web357 8、web358 9、web359 10、web360 1、web351 看到 curl_exec 函数&#xff0c;很典型的 SSRF 尝试使用 file 协议读文件&#xff1a; urlfile:///etc/passwd 成功读取到 /etc/passwd 同…