【动态规划】【字符串】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.hqwc.cn/news/325454.html

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

相关文章

alpha测试和beta测试Gamma测试的区别是什么?

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;软件测试面试题分享&#xff1a; 1000道软件测试面试题及答案&#x1f4e2;软件测试实战项目分享&#xff1a; 纯接口项目-完…

CSS基础笔记-01CSS概述

文章目录 前言CSS是什么CSS的作用CSS语法添加CSS的方法 前言 CSS是什么&#xff1f;有什么作用&#xff1f;怎么编写CSS&#xff1f;怎样添加CSS&#xff1f;本文对CSS的四个方面作了学习并形成学习笔记。 CSS是什么 CSS &#xff08;Cascading Style Sheets&#xff0c;层叠…

开源网络安全工具

开源工具代表了技术领域的一股动态力量&#xff0c;体现了创新、协作和可访问性。这些工具以透明度和社区驱动的原则开发&#xff0c;允许用户根据自己的独特需求仔细检查、修改和调整解决方案。 在网络安全领域&#xff0c;开源工具是无价的资产&#xff0c;使组织能够增强防…

kubectl常用命令(全局篇)

格式 -o [cmd] -o json|yaml|wide 如&#xff1a;输出json格式 kubectl get ns ingress-nginx -o json 获取基本信息get #查看集群基本信息 kubectl get cs|pods|nodes|ns|svc|rc|deployments kubectl get cs kubectl get pods kubectl get nodes kubectl get ns kubectl g…

P1025 [NOIP2001 提高组] 数的划分———C++(动态规划、DFS)

目录 [NOIP2001 提高组] 数的划分题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 动态规划的解题思路Code运行结果DFSCode运行结果 [NOIP2001 提高组] 数的划分 题目描述 将整数 n n n 分成 k k k 份&#xff0c;且每份不能为空&#xff0c;任意两个方案不相…

面试算法96:字符串交织

题目 输入3个字符串s1、s2和s3&#xff0c;请判断字符串s3能不能由字符串s1和s2交织而成&#xff0c;即字符串s3的所有字符都是字符串s1或s2中的字符&#xff0c;字符串s1和s2中的字符都将出现在字符串s3中且相对位置不变。例如&#xff0c;字符串"aadbbcbcac"可以由…

【Vue3+React18+TS4】1-1 : 课程介绍与学习指南

本书目录&#xff1a;点击进入 一、为什么做这样一门课程? 二、本门课的亮点有哪些? 2.1、轻松驾驭 2.2、体系系统 2.3、高效快捷 2.4、融合贯通 三、课程内容包括哪些? 四、项目实战 《在线考勤系统》 五、课适合哪些同学? 一、为什么做这样一门课程? 近十年内前端…

Android两个APP之间跳转+手机图标修改

APP之间跳转 两个APP之间跳转同样使用Intent进行跳转&#xff0c;将需要跳转的APP都下载到手机中&#xff0c;通过主APP调用需要跳转的APP包名进行跳转。 最好在其中加上try-catch语句&#xff0c;当需要跳转的APP不存在时进行错误抓取。 代码如下&#xff1a; Intent mInten…

gitlab 配置 二

一 环境说明 群晖Nas DS418DELL XPS serverGitlab ce 二 需要实现的功能 外网可以访问&#xff0c;gitlab使用https的方式访问。wiki issue 等都可以上传图片和附件。 三 操作步骤 因为群晖上有证书&#xff0c;并且由群晖做转发功能。因此证书上&#xff0c;采用群晖的证书…

数一下 1到 100 的所有整数中出现多少个数字9并输出这些数字

分析&#xff1a; 我们知道 1-100的整数 i 中&#xff0c;9会出现在十位和个位上&#xff0c;数9出现的次数可以通过以下来实现&#xff1a; 个位是9 // i % 10得到整数 i 个位上的数十位是9 // i / 10得到整数 i 除了个位数的数字 这也是做这道题之后&#xff0c;我们需要…

web学习笔记(十一)

目录 1.数据类型 1.1数据类型分类 &#xff08;1&#xff09;简单&#xff08;基本&#xff09;数据类型 &#xff08;2&#xff09;复杂&#xff08;特殊&#xff09;数据类型 1.2判断数据类型的方法 &#xff08;1&#xff09;常规判断方法&#xff1a; &#xff08;2…

机器人制作开源方案 | 智能盲道除雪小车

作者&#xff1a;汪荣顺 李明旭 马晓乐 吴泽俊 李以陈 单位&#xff1a;江汉大学 指导老师&#xff1a;张朝刚 张会利 本文论述了一种新型智能盲道除雪小车的设计与研发。由于目前的除雪设备集中在公路、城市道路、机场路面、高速公路等领域&#xff0c;但对于街道等路况的研…