LeetCode #5 Problem
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
这题是一个求最长回文子串的题目,题目的数据量不大,其实应该是可以用后缀数组做的,但是查了资料之后发现了一个神奇的算法:Manacher算法,这个算法可以在O(n)的时间复杂度下求出最长回文子串。这个算法的精妙之处就在于在字符串首尾和每两个字符之间添加一个特殊变量以规避奇数和偶数长度字符串带来的麻烦,同时引入了md和id这两个辅助变量用于在O(n)的时间内求出辅助数组P[i],也就是以每个字符为中心的回文串长度。
关于求P[i]数组,我参考了 http://blog.youkuaiyun.com/ggggiqnypgjg/article/details/6645824 的求法,原博客图文并茂相当清楚就不在赘述了。
C# Code
public class Solution
{
public string stringEncode(string str)
{
string s = "";
s += "$#";
for (int i = 0; i < str.Length; i++)
{
s += str[i];
s += "#";
}
return s;
}
public string LongestPalindrome(string str)
{
string s = stringEncode(str);
int[] p = new int[s.Length + 1];
int mx = 0, id = 0;
for (int i = 1; i <= s.Length; i++)
{
if (mx > i)
p[i] = (p[2 * id - i] < (mx - i) ? p[2 * id - i] : (mx - i));
else
p[i] = 1;
while ((i + p[i] <= s.Length - 1) && (i + p[i] >= 0) && s[i - p[i]] == s[i + p[i]])
p[i]++;
if (i + p[i] > mx)
{
mx = i + p[i];
id = i;
}
}
int max = 0, j = 0;
for (int i = 1; i < s.Length; i++)
if (p[i] > max)
{
j = i;
max = p[i];
}
int start = j - max + 1, end = j + max - 1;
string ans = "";
for (int i = start; i <= end; i++)
{
if (s[i] != '#')
{
ans += s[i];
}
}
return ans;
}
}