/*为了获取最短的回文串,需要找到字符串从头开始的最长回文子串,然后取剩下部分
的字符串的逆序加到字符串的前头,即可获得最短回文子串。所以解决该问题的关键部分是
寻找以第一个字符开始的最长回文子串,有以下几种方法:
1.采用暴力查找,大数据下会超时。
2.借用KMP算法来寻找最长回文子串,即本代码中所用方法;
3.采用Manacher算法。*/
class Solution {
public:
string shortestPalindrome(string s) {
if(s.size() <= 1) return s;
int idx = kmp_search(s);
int i = idx, j = idx+1;
while(i >= 0 && j < s.size() && s[i] == s[j]){
--i;
++j;
}
if(i >= 0){
i = idx - 1;
j = idx + 1;
while(i >= 0 && j < s.size() && s[i] == s[j]){
--i;
++j;
};
}
if(j >= s.size()) return s;
string sub = s.substr(j, s.size()-j);
reverse(sub.begin(), sub.end());
return sub + s;
}
int kmp_search(const string &s){
vector<int> next;
get_next(s, next);
int i = 0, j = s.size() - 1;
while(i < j){
if(i == -1 || s[i] == s[j]){
++i;
--j;
}
else i = next[i];
}
return j;
}
void get_next(const string &s, vector<int> &next){
next.assign(s.size(), 0);
int i = 0, j = -1;
next[i] = j;
while(i < s.size()-1){
if(j == -1 || s[i] == s[j]){
++i;
++j;
next[i] = s[i] == s[j] ? next[j] : j;
}
else j = next[j];
}
}
};