C++算法:最短回文串

简介: C++算法:最短回文串

题目

给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。

示例 1:

输入:s = “aacecaaa”

输出:“aaacecaaa”

示例 2:

输入:s = “abcd”

输出:“dcbabcd”

提示:

0 <= s.length <= 5 * 104

s 仅由小写英文字母组成

分析

我们可以将s分成两部分s1+s2,其中s1是回文,假定前面增加的字符串是s0。因为s0+s1+s2是回文,所以s0和s2是逆序。要想s0最短,就要s2最短,也就是s1最长。那么此题的本质就是:求s是回文的最长前缀。如果s不存在回文前缀,则认为s1为空。求出s1后,再求s0和s2,并返回s0+s1+s2。

求回文至少有两种办法:一,枚举回文中心,时间复杂度O(n^2)。本题会超时。二,马拉车算法,时间复杂度O(n)。比较复杂,过些天专门写篇博文介绍马拉车算法。建议将马拉车算法封装成类。

2023年4月版

class Solution {
public:
string shortestPalindrome(string s) {
if (“” == s)
{
return “”;
}
m_c = s.length();
std::string s1 = Do(s);
std::string strAdd;
for (int i = s.length() - 1; i >= s1.length(); i–)
{
strAdd += s[i];
}
return strAdd + s;
}
string Do(const string& s)
{
vector next(m_c, -1);
for (int i = 1; i < m_c; i++)
{
int iNext = next[i - 1];
while ((-1 != iNext) && (s[iNext + 1] != s[i]))
{
iNext = next[iNext];
}
next[i] = (s[i] == s[iNext + 1]) ? iNext + 1 : iNext;
}
std::string sRever(s.rbegin(), s.rend());
int i = 0, j = 0;
while ((i<m_c)&&(j<m_c))
{
while ((i < m_c) && (j < m_c) && (s[i] == sRever[j]))
{
i++;
j++;
}
if (i >= m_c - (j - i))
{
return s.substr(0, i);
}
if (j >= m_c)
{
return “”;
}
if ((i > 0) && (next[i - 1] >= 0))
{
i = next[i - 1] + 1;
}
else
{
if (i > 0)
{
i = 0;
}
else
{
j++;
}
}
}
return s.substr(0,1);
}
int m_c;
};

2023年8月版(马拉车)


class CKMP
{
public:
static vector Next(const string& s)
{
const int len = s.length();
vector vNext(len, -1);
for (int i = 1; i < len; i++)
{
int next = vNext[i - 1];
while ((-1 != next) &&(s[next + 1] != s[i]))
{
next = vNext[next];
}
vNext[i] = next + (s[next + 1] == s[i]);
}
return vNext;
}
};
class Solution {
public:
string shortestPalindrome(string s) {
vector next = CKMP::Next(s);
int n = s.length();
int preSameIndex = -1;
for (int i = n - 1; i >= 0; i–)
{
const auto& ch = s[i];
while ((-1 != preSameIndex) && (s[preSameIndex + 1] != ch))
{
preSameIndex = next[preSameIndex];
}
if (ch == s[preSameIndex + 1])
{
preSameIndex++;
}
}
string add = (preSameIndex == n - 1 ? “” : s.substr(preSameIndex + 1, n));
reverse(add.begin(), add.end());
return add + s;
}

};


其它

视频课程

如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。

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

相关文章
|
3月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
2天前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
7天前
|
算法 安全 C++
用 C++ 算法控制员工上网的软件,关键逻辑是啥?来深度解读下
在企业信息化管理中,控制员工上网的软件成为保障网络秩序与提升办公效率的关键工具。该软件基于C++语言,融合红黑树、令牌桶和滑动窗口等算法,实现网址精准过滤、流量均衡分配及异常连接监测。通过高效的数据结构与算法设计,确保企业网络资源优化配置与安全防护升级,同时尊重员工权益,助力企业数字化发展。
31 4
|
3月前
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
737 0
高精度算法(加、减、乘、除,使用c++实现)
|
3月前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
54 0
|
3月前
|
存储 算法 决策智能
【算法】博弈论(C/C++)
【算法】博弈论(C/C++)
|
3月前
|
存储 算法 C++
【算法】哈希映射(C/C++)
【算法】哈希映射(C/C++)
|
3月前
|
机器学习/深度学习 人工智能 算法
【算法】最长公共子序列(C/C++)
【算法】最长公共子序列(C/C++)
|
3月前
|
人工智能 算法 BI
一篇带你速通差分算法(C/C++)
一篇带你速通差分算法(C/C++)
|
3月前
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)