给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入:"aacecaaa"
输出:"aaacecaaa"
示例 2:
输入:"abcd"
输出:"dcbabcd"
和HDU Clairewd’s message类似
其实等价于找最长前缀回文串
(aacecaa)a是前面加a
(a)bcd是前面加dcb
这个长度枚举一下就好了
正着算一次hash,反着算一次,枚举前面添加字符的个数i,hash判断1到s.size()-i是否为回文
复杂度O(n)
class Solution {
typedef unsigned long long ULL;
const ULL key = 2333;
public:
vector a,b,p;
public:
ULL gethash(int l,int r,int cas) {
return cas ?
a[r]-a[l-1]*p[r-l+1]:
b[r]-b[l-1]*p[r-l+1];
}
public:
string shortestPalindrome(string s) {
p.push_back(1);
a.push_back(0);
b.push_back(0);
for (int i = 0; i < s.size(); i++) {
p.push_back(p[i]*key);
a.push_back(a[i]*key+s[i]);
b.push_back(b[i]*key+s[s.size()-1-i]);
}
string per = "";
for (int i = 0; i <= s.size(); i++)
if (gethash(1,s.size()-i,1) == gethash(1+i,s.size(),0)) {
for (int j = 1; j <= i; j++) per += s[s.size()-j];
return per+s;
}
s = "Error!";
return s;
}
};