Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:
Input: "babad"
Output: "bab"
Note: “aba” is also a valid answer.
Example:
Input: "cbbd"
Output: "bb"
最长回文串
思路:Manacher算法
很明显最大的P[i]值减1即为最长的回文字符串长度。所以问题来了,怎么计算P这个数组是接下来的重点。
Manacher算法增加两个辅助变量mid和maxid,mid代表的是最长回文串的中心的位置,maxid是最长回文串的边界即mid+P[mid]。
Manacher算法有个很重要的结论:IF maxid>i, P[i]>=min(P[2*mid-i],maxid-i]
这个结论怎理解呢?
如下图,我们设置位置j为i关于mid的对称点,j=2*mid-i
当maxid-i>P[i]时,以位置i为中心的最长回文串和以j为中心的最长回文串是相同的。解释一下,因为以mid为中心的最长回文串的边界是maxid,则在maxid对称点和maxid之间的字符串是回文的,所以,以位置i为中心的最长回文串和以j为中心的最长回文串是相同的。即P[i]=P[j]。
当maxid-i<=P[i]时,直观上就是以位置i为中心的最长回文串的边界超过了maxid。此时,只能在超出maxid边界继续匹配。
当maxid<=i时,直接令P[i]=1,继续匹配。
困了,代码稍晚贴出来,晚安。
关于代码我说一下,用的例子是leetcode的,在sublime上调试结果是wyyw,但在leetcode平台上是eiee,该题目在leetcode平台一共有94个test,通过了93个,第94个见鬼了,两个平台不一样。如果你发现为什么两个平台不一样,私信我。
日了狗了。。。截图如下:
#include <iostream>
#include "string"
#include "algorithm"
#include "vector"
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
string str="";
int length=s.size();
if(length<=1)
return s;
for(int i=0;i<length;i++)
{
str+="#";
str+=s[i];
}
str+="#";
return manacher(str,s);
}
string manacher(string str,string s);
};
string Solution::manacher(string str,string s)
{
int mid=0,maxid=0;
int length=str.size();
vector<int> P(length,0);
for(int i=0;i<length;i++)
{
if(maxid>i)
{
P[i]=min(P[2*mid-1],maxid-i);
}
else{
P[i]=1;
}
while(i-P[i]>=0&&i+P[i]<=length&&str[i+P[i]]==str[i-P[i]])
{
P[i]++;
}
if(maxid<P[i]+i)
{
maxid=i+P[i];
mid=i;
}
}
int max=0,index=0;
for(int i=0;i<length;i++)
{
if(max<=P[i])
{
index=i;
max=P[i];
}
}
string subStr="";
if(index%2==1)
{
subStr=s.substr(index/2-(max-1)/2,max-1);
}
else{
subStr=s.substr(index/2-max/2,max-1);
}
return subStr;
}
int main()
{
string str="apqjpwedlhmvvpexxnntxheeynxmgzwxhnhfdvziuxnuusymklgcacndoyhqkoahnkyaikohwkmnuphipftmzmihvmoetskioeypwjujvvusaxynzxxdugnebsisrtgeujkqkgwjuplijhluumqcdurovyjsbowmnqndejwkihzbbdyxjunkduyqeihektaknbmkzgnnmgywylulxwyywrvieqfenjeljofkqqqisdjsbfkvqgahxwkfkcucvrbbpyhwkfztjdboavtfynrudneieelwlcezqsuhmllcsadcnoyemsfdlrijoyj";
int len=str.size();
Solution sol;
string str1=sol.longestPalindrome(str);
for(int i=0;i<str1.length();i++)
{
cout<<str1[i];
}
return 0;
}