【动态规划】【字符串】132.分割回文串 II

作者推荐

【动态规划】【字符串】扰乱字符串

本文涉及的基础知识点

动态规划 字符串

LeetCode132. 分割回文串 II

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
返回符合要求的 最少分割次数 。
示例 1:
输入:s = “aab”
输出:1
解释:只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。
示例 2:
输入:s = “a”
输出:0
示例 3:
输入:s = “ab”
输出:1
提示:
1 <= s.length <= 2000
s 仅由小写英文字母组成

动态规划

分两步:
一,枚举回文的中心,记录所有的回文。空间复杂度和时间复杂度都是O(nn)。
二,通过动态规划计算所有所有前缀可以差分成多少个不重叠的子字符串。空间复杂度O(n),时间复杂度是O(nn)。

变量解析

vRightToLeft(m_c)vRightToLeft[i] 包括元素j,表示s[i,j],是回文串。 vRightToLeft不重复遗漏的记录所有回文串。
dp[i]记录s[0,i]最少可以划分成多少个不重叠的回文子串

态规范分析

动态规划的状态表示dp[i]记录s[0,i]最少可以划分成多少个不重叠不遗漏的回文子串
动态规划的转移方程如果s[left,i]是回文,dp[i]=min(dp[i],dp[left-1]+1)
动态规划的初始状态全部为INT_MAX
动态规划的填表顺序i从小到大。由短到长处理子字符串,确保动态规划的无后效性
动态规划的返回值dp.back()-1

代码

核心代码

class Solution {
public:int minCut(string s) {m_c = s.length();vector<vector<int>> vRightToLeft(m_c);//cRightToLeft[i] 包括元素j,表示s[i,j],是回文串。for (int i = 0; i < m_c; i++){for (int left = i, right = i; (left >= 0) && (right < m_c)&&(s[left]==s[right]); left--, right++){//奇数长度回文vRightToLeft[right].emplace_back(left);}for (int left = i, right = i+1; (left >= 0) && (right < m_c) && (s[left] == s[right]); left--, right++){//偶数长度回文vRightToLeft[right].emplace_back(left);}}vector<int> dp(m_c,INT_MAX);for (int i = 0; i < m_c; i++){for (const auto& left : vRightToLeft[i]){dp[i] = min(dp[i], 1 + (left > 0 ? dp[left - 1] : 0));}}return dp.back()-1;}int m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{string s;	{Solution sln;s = "aab";auto res = sln.minCut(s);Assert(1, res);}{Solution sln;s = "a";auto res = sln.minCut(s);Assert(0, res);}{Solution sln;s = "ab";auto res = sln.minCut(s);Assert(1, res);}
}

2023年1月版

class Solution {
public:
int minCut(string s) {
m_c = s.length();
vector<vector> is;
is.assign(m_c, vector(m_c+1));
for (int c = 0; c < m_c; c++)
{
//长度为1的字符串一定是回文
is[c][1] = true;
}
for (int c = 0; c + 1 < m_c; c++)
{
is[c][2] = (s[c] == s[c + 1]);
}
for (int len = 3; len <= m_c; len++)
{
for (int c = 0; c + len - 1 < m_c; c++)
{
is[c][len] = is[c + 1][len - 2] && (s[c] == s[c + len - 1]);
}
}
//最少多少个回文构成
vector dp(m_c + 1,INT_MAX);
dp[0] = 0;
for (int c = 0; c < m_c; c++)
{
for (int len = 1; len <= m_c; len++)
{
if (is[c][len] && (c+len <= m_c ))
{
dp[c + len] = min(dp[c + len], dp[c] + 1);
}
}
}
return dp[m_c] - 1;
}
int m_c;
};

2023年8月

//马拉车计算回文回文
class CPalindrome
{
public:
//vOddHalfLen[i]表示 以s[i]为中心,且长度为奇数的最长回文的半长,包括s[i]
//比如:“aba” vOddHalfLen[1]为2 “abba” vEvenHalfLen[1]为2
static void Do(vector& vOddHalfLen, vector& vEvenHalfLen,const string& s)
{
vector v;
for (const auto& ch : s)
{
v.emplace_back(ch);
v.emplace_back(‘*’);
}
v.pop_back();
const int len = v.size();
vector vHalfLen(len);
int center = -1, r = -1;
//center是对称中心,r是其右边界(闭)
for (int i = 0; i < len; i++)
{
int tmp = 1;
if (i <= r)
{
int pre = center - (i - center);
tmp = min(vHalfLen[pre], r - i + 1);
}
for (tmp++; (i + tmp - 1 < len) && (i - tmp + 1 >= 0) && (v[i + tmp - 1] == v[i - tmp + 1]); tmp++);
vHalfLen[i] = --tmp;
const int iNewR = i + tmp - 1;
if (iNewR > r)
{
r = iNewR;
center = i;
}
}
vOddHalfLen.resize(s.length());
vEvenHalfLen.resize(s.length());
for (int i = 0; i < len; i++)
{
if (i & 1)
{
vEvenHalfLen[i / 2] = vHalfLen[i] / 2;

		}else{vOddHalfLen[i / 2] = (vHalfLen[i]+1) / 2 ;				}}
}

};
class Solution {
public:
int minCut(string s) {
m_c = s.length();
vector vOddHalfLen, vEvenHalfLen;
CPalindrome::Do(vOddHalfLen, vEvenHalfLen,s);
//邻接表
vector<vector> vNeiBo(m_c+1);
for (int i = 0; i < m_c; i++)
{
for (int len = 1; len <= vOddHalfLen[i]; len++)
{
const int cur = i - len + 1;
const int next = i + len;
vNeiBo[cur].emplace_back(next);
}
for (int len = 1; len <= vEvenHalfLen[i]; len++)
{
const int cur = i - len + 1;
const int next = i + len+1;
vNeiBo[cur].emplace_back(next);
}
}
queue que;
que.emplace(0);
vector vDis(m_c+1, -1);
vDis[0] = 0;
while (que.size())
{
const int cur = que.front();
que.pop();
const int curDis = vDis[cur];
for (const auto& next : vNeiBo[cur])
{
if (-1 != vDis[next])
{
continue;
}
vDis[next] = curDis + 1;
que.emplace(next);
}
}
return vDis.back() - 1;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

基于R语言(SEM)结构方程模型教程

详情点击链接&#xff1a;基于R语言&#xff08;SEM&#xff09;结构方程模型教程 01、R/Rstudio (2)R语言基本操作&#xff0c;包括向量、矩阵、数据框及数据列表等生成和数据提取等 (3)R语言数据文件读取、整理&#xff08;清洗&#xff09;、结果存储等&#xff08;含tidve…

提升图像分割精度:学习UNet++算法

文章目录 一、UNet 算法简介1.1 什么是 UNet 算法1.2 UNet 的优缺点1.3 UNet 在图像分割领域的应用 二、准备工作2.1 Python 环境配置2.2 相关库的安装 三、数据处理3.1 数据的获取与预处理3.2 数据的可视化与分析 四、网络结构4.1 UNet 的网络结构4.2 UNet 各层的作用 五、训练…

Simply简洁博客主题源码 | EmlogPro主题模版

Simply是一款简约风格的Emlog博客模板&#xff0c;响应式布局、界面简单大方&#xff0c;实用性强&#xff01; 支持夜间模式&#xff0c;采用localStorage存储配置。IOS系统下支持随系统自动切换浅/深色模式。 文章页支持显示文章字数及阅读时间。 支持http/https 响应式主…

基于PyTorch的Transformer组件实现

最近看了不少介绍LLM工作原理的文章&#xff0c;发现每一篇都会试图跟读者讲明白作为baseline的Transformer架构到底长啥样。但是好像比较少有代码实现的示例和具体的例子帮助理解。于是自己也想尝试着写一篇含有代码实现和具体例子解释的文章&#xff0c;希望能够给喜欢编程朋…

fmincon函数求解非线性超越方程的学习记录

最近的算法中用到了fmincon函数&#xff0c;寻找多变量非线性方程最小值的函数&#xff1b;因此学习一下&#xff1b; fmincon函数的基础语法如下所示&#xff1a; fmincon函数是为了求解下列方程的最小值&#xff1b; b 和 beq 是向量&#xff0c;A 和 Aeq 是矩阵&#xff0c…

2024年最新51单片机+Proteus嵌入式开发入门实战完整版教程

我们为什么要学嵌入式开发&#xff1f; 嵌入式系统是一种专为特定任务或特定应用设计的计算机系统。与通用计算机系统不同&#xff0c;嵌入式系统通常具有更小的体积、更低的功耗和更强的可靠性。由于这些特点&#xff0c;嵌入式系统广泛应用于工业控制、医疗设备、智能家居、…

【C++进阶04】STL中map、set、multimap、multiset的介绍及使用

一、关联式容器 vector/list/deque… 这些容器统称为序列式容器 因为其底层为线性序列的数据结构 里面存储的是元素本身 map/set… 这些容器统称为关联式容器 关联式容器也是用来存储数据的 与序列式容器不同的是 其里面存储的是<key, value>结构的键值对 在数据检索时…

JVM工作原理与实战(七):类的生命周期-初始化阶段

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类的生命周期 1.加载&#xff08;Loading&#xff09; 2.连接&#xff08;Linking&#xff09; 3.初始化&#xff08;Initialization&#xff09; 4.使用&#xff08;Using&…

canvas文字设置(含最大宽度)的示例

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

Linux tty命令教程:掌握Linux终端的使用(附案例详解和注意事项)

Linux tty命令介绍 tty命令在Linux中是一个简单的实用程序&#xff0c;用于检查连接到标准输入的终端。tty是“teletypewriter”的缩写&#xff0c;但通常被称为终端&#xff0c;它允许您通过将数据&#xff08;您的输入&#xff09;传递给系统并显示系统产生的输出来与系统进…

springboot + vue 前后端加密传输 RSA互相加解密、加签验签、密钥对生成

参考 二、关于PKCS#1和PKCS#8格式密钥 由于Java非对称加解密、加验签都是采用PKCS#8格式的密钥&#xff0c;PKCS#1格式的密钥跑不通&#xff0c;这里先简单介绍一下两者的区别。 1、简介 PKCS#1和PKCS#8是两个不同的数字证书标准。 PKCS#1是一个公钥加密标准&#xff0c;它…

【解决|三方工具】导入 XChart 后提示丢失关于 TMPPro 工具引用

开发平台&#xff1a;Unity 2021 版本 插件版本&#xff1a;XChart 3.0&#xff1a;官方文档 - https://github.com/XCharts-Team/XCharts   问题描述 导入 XChart 插件至 Unity 中出现 目录&#xff1a;Component、Theme 等提示丢失 TMPPro&#xff08;TextMeshPro 工具&…

微信小程序的5种打开页面方式

wx.navigateTo&#xff1a;打开新页面 使用 wx.navigateTo 可以打开一个新的页面&#xff0c;新页面会被放置在当前页面的上层。 wx.navigateTo({url: /pages/nextPage/nextPage });wx.redirectTo&#xff1a;关闭当前页面&#xff0c;打开新页面 使用 wx.redirectTo 关闭当…

2024年,Web3技术的“iPhone时刻”会出现吗?

出品&#xff5c;欧科云链研究院 关于2024年的Web3市场&#xff0c;大多数人目前是持乐观态度的。随着宏观政策稳定&#xff0c;美国和香港地区不断释放加密资产现货ETF的利好&#xff0c;叠加铭文热潮及减半周期临近&#xff0c;市场对Web3及加密资产的兴趣正持续上涨。年后的…

[蓝桥杯学习]树的直径与重心

树的直径 定义 为什么不直接说&#xff08;u,v&#xff09;是两个叶子&#xff0c;可能有如下情况&#xff1a; 这是一条链&#xff0c;且u为根&#xff0c;但&#xff0c;度数为1 下面这个情况是不经过根的。 求解方法 如果设根u的深度为0时&#xff0c;直径就是深度dep[v]…

代码随想录刷题第三十八天| 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

代码随想录刷题第三十八天 动态规划基础理论 斐波那契数 (LC 509) 题目思路&#xff1a; 代码实现&#xff1a; class Solution:def fib(self, n: int) -> int:if n<1: return ndp [0 for _ in range(n1)]dp[1] 1for i in range(2, n1):dp[i] dp[i-1]dp[i-2] …

教学/直播/会议触摸一体机定制_基于展锐T820安卓核心板方案

触控一体机是一种集先进的触摸屏、工控和计算机技术于一体的设备。它取代了传统的键盘鼠标输入功能&#xff0c;广泛应用于教学、培训、工业、会议、直播、高新科技展示等领域。触摸一体机的应用提升了教学、会议和展示的互动性和信息交流。 触摸一体机方案基于国产6nm旗舰芯片…

【Spring实战】23 Spring Actuator 常用的自定义

文章目录 1. 自定义健康指示器2. 自定义端点3. 自定义端点路径4. 自定义 Actuator 端点的访问权限5. 启动服务6. 访问自定义的 custom 端点总结 Spring Actuator 是 Spring 框架的一个模块&#xff0c;为开发人员提供了一套强大的监控和管理功能。上一篇 【Spring实战】22 Spri…

1.5 CHALLENGES IN PARALLEL PROGRAMMING

是什么让并行编程变得困难&#xff1f;有人曾经说过&#xff0c;如果你不关心性能&#xff0c;并行编程很容易。你可以在一小时内编写一个并行程序。但是&#xff0c;如果你不在乎性能&#xff0c;为什么要费心写一个并行程序呢&#xff1f; 这本书解决了在并行编程中实现高性…

C语言全面学习基础阶段01—C生万物

如何学好 C 语言 1. 鼓励你&#xff0c;为你叫好。 C 生万物 编程之本 长远 IT 职业发展的首选 C 语言是母体语言&#xff0c;是人机交互接近底层的桥梁 学会 C/C &#xff0c;相当于掌握技术核心 知识点一竿子打通。 IT 行业&#xff0c;一般每 10 年就有一次变革 40 年间&a…