【动态规划】【字符串】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.mfbz.cn/a/296000.html

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

相关文章

11.2 Linux串口驱动框架

tty 驱动程序框架 tty 驱动程序从下往上分别是设备驱动层、行规程、终端虚拟化、TTY I/O层&#xff0c;它们的功能如下&#xff1a; 设备驱动层&#xff1a;用于驱动设备&#xff0c;如串口、显示器、键盘等。行规程&#xff1a;用于处理控制字符、回显输入数据、缓存输入数据…

矩阵的乘法

首先矩阵的乘法定义如下&#xff1a; #include <stdio.h> int main() { int i 0; int j 0; int arr[20][20] { 0 }; int str[20][20] { 0 }; int s[20][20] { 0 }; int n1 0; int n2 0; int m2 0; int z 0; int m1 0;…

使用IDEA官方docker插件构建镜像

此方法同样适用于jetbrains系列的其他开发软件 在IDEA中&#xff0c;如果是maven项目&#xff0c;可以使用插件 <plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.2.2</version> &…

用于查询性能预测的计划结构深度神经网络模型--大数据计算基础大作业

用于查询性能预测的计划结构深度神经网络模型 论文阅读和复现 24.【X1.1】 在关系数据库查询优化领域&#xff0c;对查询时间的估计准确性直接决定了查询优化结果&#xff0c;进而影响到数据库整体的查询效率。但由于数据库自身的复杂性&#xff0c;查询时间受到数据分布、数据…

Linux操作实例 – 输入输出重定向

Linux操作实例 – 输入输出重定向 Input & Output Redirection Examples in Linux By Jackson 1. 前言 在操作计算机的时候&#xff0c;我们能够很容易通过键盘、鼠标给计算机输入信息&#xff08;例如&#xff1a;写公文、邮件&#xff0c;同时通过显示器得到输出。这就…

【AI视野·今日Sound 声学论文速览 第三十九期】Tue, 2 Jan 2024

AI视野今日CS.Sound 声学论文速览 Tue, 2 Jan 2024 Totally 7 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Enhancing Pre-trained ASR System Fine-tuning for Dysarthric Speech Recognition using Adversarial Data Augmentation Authors Huimen…

数据安全保护体系的设计原则

目录 引言 数据的分类分级原则 数据的分类分级是个长期且动态的过程 数据的分类分级应结合实际应用和业务特性 建立数据分类分级制度和体系也是非常重要的 最小化原则 企业需要对数据访问的用户进行身份验证 企业需要明确用户访问数据的目的是什么 企业需要梳理数据访问…

CentOS 7 安装 PPTP

环境&#xff1a; 阿里云试用机&#xff1a; 外网IP&#xff1a;114.55.80.150 内网IP&#xff1a;172.28.11.92 一、服务器安装 PPTP 1、安装 yum install epel-release -y 2、安装pptp yum install pptpd iptables-services -y 3、修改配置 vim /etc/pptpd.conf# 最…

DS|二叉树

题目一&#xff1a;DS二叉树 -- 二叉树构建与遍历 题目描述&#xff1a; 给定一颗二叉树的逻辑结构如下图&#xff0c;&#xff08;先序遍历的结果&#xff0c;空树用字符‘#’表示&#xff0c;例如AB#C##D##&#xff09;&#xff0c;建立该二叉树的二叉链式存储结构&#xf…

【面试高频算法解析】算法练习5 深度优先搜索

前言 本专栏旨在通过分类学习算法&#xff0c;使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目&#xff0c;帮助您深度理解每种算法&#xff0c;避免出现刷了很多算法题&#xff0c;还是一知半解的状态 专栏导航 二分查找回溯&#xff08;Backtracking&…

【代码随想录】刷题笔记Day46

前言 刚考完自辩&#xff0c;Chat回答举例什么的真方便。早上做组会PPT去了&#xff0c;火速来刷题&#xff01; 139. 单词拆分 - 力扣&#xff08;LeetCode&#xff09; 单词是物品&#xff0c;字符串s是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把…

1.3进制,码(8421),化简规则、卡诺图化简、性质,触发器(转换与设计、应用),电路图,电路设计

十进制与原码、反码、补码之间的转换 正数的原码、反码、补码相同&#xff0c;符号位为0 负数的原码为、符号位1&#xff0c;二进制数 反码&#xff0c;符号位不变、其它取反&#xff0c; 补码为&#xff1a;反码最低有效位1 运算 卡诺图化简 奇偶校验码 检查1的个数&…

使用CentOS 7.6搭建HTTP隧道代理服务器

在现代网络环境中&#xff0c;HTTP隧道代理服务器因其灵活性和安全性而受到广泛关注。CentOS 7.6&#xff0c;作为一个稳定且功能强大的Linux发行版&#xff0c;为搭建此类服务器提供了坚实的基础。 首先&#xff0c;我们需要明确HTTP隧道代理的基本原理。HTTP隧道代理允许客户…

字节填充与0比特填充以及数据链路的基本问题

目录 字节填充&#xff1a; 比特填充&#xff1a; 数据链路有三个基本问题 1.封装成帧 2.透明传输 3.差错检测 首先介绍一下PPP的帧结构&#xff1a; 首部的第一个字段和尾部的第二个字段都是标志字段F(Flag)&#xff0c;规定为0x7E (符号“0x”表示它后面的字符是用十六…

python练习3【题解///考点列出///错题改正】

一、单选题 1.【单选题】 ——可迭代对象 下列哪个选项是可迭代对象&#xff08; D&#xff09;&#xff1f; A.(1,2,3,4,5) B.[2,3,4,5,6] C.{a:3,b:5} D.以上全部 知识点补充——【可迭代对象】 可迭代对象&#xff08;iterable&#xff09;是指可以通过迭代&#xff…

发票信息提取v1.2.0

程序介绍 “发票信息提取”是一款用于提取电子发票的PDF、XML文件中的开票信息到excel表格的软件&#xff0c;无需联网及进行复杂配置&#xff0c;打开即用。目前支持增值税电子发票&#xff08;非数电票&#xff09;原始PDF文件&#xff0c;及数电票的XML文件。 更新内容 增加…

【I2C】i2c-tools工具使用,以及开发调试

i2c调试 eeprom 手动创建eeprom设备调试&#xff0c;例如0x50 是FRU的地址&#xff0c;i2c-3是bus 创建设备 echo 24c32 0x50 > /sys/bus/i2c/devices/i2c-4/new_device如果设备正确&#xff0c;将成功被创建&#xff0c;并且生成/sys/bus/i2c/devices/4-0050/eeprom&am…

智能语音机器人NXCallbot

受出海公司业务全球化的影响&#xff0c;智能客服逐渐从便捷应用变为市场刚需。新基建七大领域中&#xff0c;人工智能及场景应用的基础建设是最核心的领域&#xff0c;而智能客服作为商业化实际应用的核心场景之一&#xff0c;能提升企业运营效率&#xff0c;为行业客户赋能。…

智能分析网关V4在工业园区周界防范场景中的应用

一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;对…

“编程界的隐形斗篷:C语言作用域与生命周期的喜怒哀乐”

少年们&#xff0c;大家好。我是博主那一脸阳光。 前言&#xff1a;理解C语言作用域与生命周期&#xff0c;犹如掌握了变量在程序中的“活动地带”与“存活时刻”&#xff0c;有助于避免数据冲突、优化内存使用、提升代码质量和模块化程度&#xff0c;增强程序稳定性和安全性…
最新文章