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

相关推荐
Dream_Snowar28 分钟前
速通Python 第三节
开发语言·python
唐诺38 分钟前
几种广泛使用的 C++ 编译器
c++·编译器
XH华1 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_1 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
落魄君子2 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
冷眼看人间恩怨2 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
菜鸡中的奋斗鸡→挣扎鸡2 小时前
滑动窗口 + 算法复习
数据结构·算法
信号处理学渣2 小时前
matlab画图,选择性显示legend标签
开发语言·matlab