[LeetCode] 214. Shortest Palindrome 最短回文串
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<int> 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 题目汇总