题目:214. 最短回文串
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入: "aacecaaa"
输出: "aaacecaaa"
示例 2:
输入: "abcd"
输出: "dcbabcd"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
基本思想1:KMP
本题是在字符串的前面加上该字符串的后缀串的逆序,使得最终构成最短的回文串,也就是我们需要找到前缀串中最长的回文串。
如何寻找前缀串中最长的回文串?KMP
- 将当前串的逆序作为查询串,当前串作为模式串,当查询串的指针指到最后时,模式串的指针所指的位置作为后缀串的起始位置
具体分析参考:官方题解
class Solution {
public:
string shortestPalindrome(string s) {
//KMP
if(s.length() < 2)
return s;
string pattern = s;//模式串
reverse(s.begin(), s.end());//查询串
int pos = kmp(pattern, s);
if(pos == s.length())//本身是回文串
return s;
string temp = pattern.substr(pos, pattern.length() - pos);
reverse(temp.begin(), temp.end());
string res = temp + pattern;
return res;
}
int kmp(string pattern, string s){
vector<int> next = fun(pattern);
int i = 0, j = 0;
int lens = s.size(), lenp = pattern.size();
while(i < lens && j < lenp){
if(j == -1 || s[i] == pattern[j]){
++i;
++j;
}
else{
j = next[j];
}
}
return j;
}
vector<int> fun(string p){
vector<int> res(p.length(), -1);
int j = 0, k = -1;
while(j < p.length() - 1){
if(k == -1 || p[k] == p[j]){
if(p[++k] == p[++j])
res[j] = res[k];
else
res[j] = k;
}
else
k = res[k];
}
return res;
}
};
基本思想2:中心扩展(超时了)
从中间开始判断,以当前字符或者当前字符(一个中心)和当前字符左边的字符(两个中心)为中心进行求解。
class Solution {
public:
int len;
string shortestPalindrome(string s) {
len = s.length();
string res = "";
if(len == 0)
return res;
int left, right;
if(len % 2 == 0){
right = len / 2;
left = right - 1;
}
else{
left = right = len / 2;
}
while(left >= 0 || right < len){
if(left >= 0){
fun(s, res, left - 1, left + 1);
fun(s, res, left - 1, left);
--left;
}
if(right < len){
fun(s, res, right - 1, right + 1);
fun(s, res, right - 1, right);
++right;
}
if(res.size())
break;
}
return res;
}
void fun(string s, string &res, int l, int r){
string temp, cur;
while(l >= 0 && r < len){
if(s[l] != s[r]){
break;
}
--l;
++r;
}
if(l == -1 && r == len)//本身就是回文
res = s;
if(l < 0 && r < len){
//向左扩展
temp = s.substr(r, len - r);
reverse(temp.begin(), temp.end());
cur = temp + s;
if(res.size() == 0 || res.size() > cur.size())
res = cur;
}
}
};