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.
Example 1:
Input:"aacecaaa"
Output:"aaacecaaa"
Example 2:
Input:"abcd"
Output:"dcbabcd"
给一个字符串s,允许在它的前面加字符使其变成回文字符串,找出最短的回文字符串。
解法1: 暴力匹配算法brute force,无法通过OJ,需要用比较巧妙的方法来解。
解法2: KMP算法。
解法3: Manacher's算法。
参考:从头到尾彻底理解KMP
Java:
public class Solution {
public String shortestPalindrome(String s) {
String r = new StringBuilder(s).reverse().toString();
String t = s + "#" + r;
int[] next = new int[t.length()];
for (int i = 1; i < t.length(); ++i) {
int j = next[i - 1];
while (j > 0 && t.charAt(i) != t.charAt(j)) j = next[j - 1];
j += (t.charAt(i) == t.charAt(j)) ? 1 : 0;
next[i] = j;
}
return r.substring(0, s.length() - next[t.length() - 1]) + s;
}
}
Python: KMP
class Solution(object):
def shortestPalindrome(self, s):
def getPrefix(pattern):
prefix = [-1] * len(pattern)
j = -1
for i in xrange(1, len(pattern)):
while j > -1 and pattern[j+1] != pattern[i]:
j = prefix[j]
if pattern[j+1] == pattern[i]:
j += 1
prefix[i] = j
return prefix
if not s:
return s
A = s + s[::-1]
prefix = getPrefix(A)
i = prefix[-1]
while i >= len(s):
i = prefix[i]
return s[i+1:][::-1] + s
Python: Manacher's
class Solution(object):
def shortestPalindrome(self, s):
def preProcess(s):
if not s:
return ['^', '$']
string = ['^']
for c in s:
string += ['#', c]
string += ['#', '$']
return string
string = preProcess(s)
palindrome = [0] * len(string)
center, right = 0, 0
for i in xrange(1, len(string) - 1):
i_mirror = 2 * center - i
if right > i:
palindrome[i] = min(right - i, palindrome[i_mirror])
else:
palindrome[i] = 0
while string[i + 1 + palindrome[i]] == string[i - 1 - palindrome[i]]:
palindrome[i] += 1
if i + palindrome[i] > right:
center, right = i, i + palindrome[i]
max_len = 0
for i in xrange(1, len(string) - 1):
if i - palindrome[i] == 1:
max_len = palindrome[i]
return s[len(s)-1:max_len-1:-1] + s
C++:
class Solution {
public:
string shortestPalindrome(string s) {
string r = s;
reverse(r.begin(), r.end());
string t = s + "#" + r;
vector next(t.size(), 0);
for (int i = 1; i < t.size(); ++i) {
int j = next[i - 1];
while (j > 0 && t[i] != t[j]) j = next[j - 1];
next[i] = (j += t[i] == t[j]);
}
return r.substr(0, s.size() - next.back()) + s;
}
};
类似题目:
[LeetCode] 9. Palindrome Number 验证回文数字
[LeetCode] 5. Longest Palindromic Substring 最长回文子串
[LeetCode] 516. Longest Palindromic Subsequence 最长回文子序列
[LeetCode] 125. Valid Palindrome 验证回文字符串
[LeetCode] 409. Longest Palindrome
All LeetCode Questions List 题目汇总