题目:
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; } }
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