# LeetCode5：Longest Palindromic Substring

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.

#include <iostream>
#include <vector>
using namespace std;

/**

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.
*/

class Solution {
public:
//Manacher算法（O(n))
string longestPalindrome(string s) {
string p;
if(s.empty())
return p;
int id = 0;
int mx = 0;
//以下对要操作的副本str进行格式化，使得其为奇数
string str("^");
for(int i = 0; i < s.size(); i++)
{
str += "#";
str += s[i];
}
str += "#$"; vector<int> r(str.size(), 0); for(int i = 1; i < str.size()-1; i++) { if(mx > i) r[i] = min(r[2*id - i], mx - i); else r[i] = 1; while(str[i+r[i]] == str[i-r[i]])//为了防止越界，str头尾插入了'^'和'$'字符
r[i]++;
if(r[i] + i > mx)
{
mx = r[i] + i;
id = i;
}
}

int maxlen = 0;
int maxid = 0;
for(int i = 1; i < str.size()-1; i++)
{
if(r[i] > maxlen)
{
maxlen = r[i];
maxid = i;
}
}
//(maxid-1)/2为原字符串中最长回文字串中心字符位置
//(maxlen-1)/2为原字符串中最长回文子串半径
//maxlen-1为原字符串中最长回文字串长度
return s.substr((maxid-1)/2 - (maxlen-1)/2, maxlen-1);

}

//DP O(n*n)
string longestPalindrome2(string s) {
string p;
if(s.empty())
return p;
int len = s.size();
vector<vector<bool>> dp(len, vector<bool>(len, false));//dp[i][j]表示i~j的字串是否为回文串
int maxstart = 0;
int maxlen = 1;
for(int i = 0; i < len-1; i++)
{
dp[i][i] = true;
if(s[i] == s[i+1])
{
dp[i][i+1] = true;
maxstart = i;
maxlen = 2;
}
}

for(int l = 3; l <= len; l++)
{
for(int i = 0; i < len-l+1; i++)
{
int j = i+l-1;
if(s[i] == s[j] && dp[i+1][j-1])
{
dp[i][j] = true;
maxstart = i;
maxlen = l;
}

}
}
return s.substr(maxstart, maxlen);

}

//中心法，以每一个字符作为回文串中心，向两边扩展
string longestPalindrome3(string s) {
string p;
if(s.empty())
return p;
int len = s.size();
int maxstart = 0;
int maxlen = 0;
for(int i = 0; i < len; i++)
{
int l = i-1;
int r = i+1;
int tmpmax = 1;//已i为中心的回文串：奇数
while(l >= 0 && r < len && s[l--] == s[r++])
tmpmax++;
if(maxlen < tmpmax*2 -1)
{
maxlen = tmpmax*2 -1;
maxstart = l+1;
}

int l2 = i;
int r2 = i+1;
int tmpmax2 = 0;//已i和i+1为中心的回文串，偶数时
while(l2 >= 0 && r2 < len && s[l2--] == s[r2++])
tmpmax2++;

if(maxlen < tmpmax2*2)
{
maxlen = tmpmax2*2;
maxstart = l2+1;
}

}

return s.substr(maxstart, maxlen);

}

};

int main(void)
{
string s("abbacdd");
Solution solution;
string p = solution.longestPalindrome3(s);
cout<<p<<endl;
return 0;
}
-----------------------我和我追猪的梦-----------------------------------------------------------------

posted @ 2014-05-01 13:22  mickole  阅读(301)  评论(0编辑  收藏  举报