题目:
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
For example:
Given "aacecaaa"
, return "aaacecaaa"
.
Given "abcd"
, return "dcbabcd"
.
先制作原字符串的对称镜像字符串,如s = "abcd", 镜像a = "abcddcba"。
然后对新字符串a,按KMP算法求Prefix的方法,求Prefix, 得【0, 0, 0, 0, 0, 0, 0, 1】,然后s.length() - prefix[2 * s.length()-1] 即为需要复制到s前的s尾部字符串的个数。
c++版:
class Solution {
public:
string shortestPalindrome(string s) {
string result = "";
if(s.length() == 0)
return result;
string a = s + string(s.rbegin(), s.rend());
vector<int> prefix(2 * s.length());
for(int i = 1; i < 2 * s.length(); i++) {
int j = prefix[i-1];
while(j > 0 && a[i] != a[j])
j = prefix[j-1];
if(a[i] == a[j])
j++;
prefix[i] = j;
}
int count = s.length() - equal[2 * s.length()-1];
return string(s.rbegin(), s.rbegin() + count) + s;
}
};
Java 版:
public class Solution {
public String shortestPalindrome(String s) {
String result = "";
if(s.length() == 0)
return result;
int[] prefix = new int[s.length() * 2];
String mirror = s + new StringBuilder(s).reverse().toString();
for(int i = 1; i < s.length() * 2; i++) {
int j = prefix[i-1];
while(mirror.charAt(j) != mirror.charAt(i) && j > 0)
j = prefix[j-1];
if(mirror.charAt(i) == mirror.charAt(j))
prefix[i] = j + 1;
else
prefix[i] = 0;
}
int count = s.length() - prefix[s.length() * 2 -1];
result = new StringBuilder(s.substring(s.length()-count, s.length())).reverse().toString() + s;
return result;
}
}
Python版:
class Solution:
# @param {string} s
# @return {string}
def shortestPalindrome(self, s):
result = ""
if len(s) == 0:
return result
s1 = s + s[::-1]
pre = [0] * len(s1)
for i in range(1, len(s1)):
j = pre[i-1]
while j > 0 and s1[i] != s1[j]:
j = pre[j-1]
if s1[i] == s1[j]:
pre[i] = j + 1
else:
pre[i] = 0
count = len(s) - pre[len(s1)-1]
s2 = s[len(s)-1:len(s)-count-1:-1]
return s2 + s