C++算法:分割回文串

题目

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。

返回符合要求的 最少分割次数 。

示例 1:

输入:s = "aab"

输出:1

解释:只需一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。

示例 2:

输入:s = "a"

输出:0

示例 3:

输入:s = "ab"

输出:1

提示:

1 <= s.length <= 2000

s 仅由小写英文字母组成

2023年1月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<int> 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<int> 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<int> que;
	que.emplace(0);
	vector<int> 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;

};

其它

视频课程

如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。
https://edu.csdn.net/course/detail/38771

我的其它课程
https://edu.csdn.net/lecturer/6176

测试环境

win7 VS2019 C++17

相关下载

doc版文档,排版好
https://download.csdn.net/download/he_zhidan/88348653

相关推荐
浮生如梦_27 分钟前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师2 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown3 小时前
【数据结构】选择排序
数据结构·算法·排序算法
记录成长java4 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山4 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
青花瓷4 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode