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.
//自己的解法 O(n^2)
class Solution {
public:
string longestPalindrome(string s)
{
int center = 0, length = 0, center1 = 0, length1 = 0;
for (int i=0;i<s.size();i++)
{
int count = 0;//aca这种
while(i-count>=0&&i+count<s.size())
{
if (s[i-count] != s[i+count])
break;
count++;
}
count--;
center = count>length?i:center;
length = count>length?count:length;
count = 0;//acca这种
while(i-count>=0&&i+1+count<s.size())
{
if (s[i-count] != s[i+1+count])
break;
count++;
}
center1 = count>length1?i:center1;
length1 = count>length1?count:length1;
}
return 2*length+1>2*length1?s.substr(center-length, 2*length+1):s.substr(center1-length1+1, 2*length1);
}
};
动态规划 O(n^2) 时间上比解法1慢好多
true i == j
p[i][j] = s[i] == s[j] j=i+1
s[i] == s[j]&&p[i+1][j-1] j>i+1
class Solution {
public:
string longestPalindrome(string s)
{
int left = 0, length = 0;
vector<vector<int> > p(s.size(), vector<int> (s.size(), false));
for (int j=0;j<s.size();j++)//注意i j下标以及起始 范围
{
for(int i=0;i<=j;i++)
{
if (i == j)
p[i][j] = true;
if(j == i+1)
p[i][j] = s[i] == s[j];
if (j>i+1)
p[i][j] = s[i] == s[j]&&p[i+1][j-1];
if(p[i][j]&&j-i+1>length)
{
left = i;
length = j-i+1;
}
}
}
return s.substr(left, length);
}
};
//马拉车算法O(n)
//http://www.cnblogs.com/grandyang/p/4475985.html
class Solution {
public:
string longestPalindrome(string s) {
// Insert '#' 这样不用区分acca和aca两种情况
string t = "$#";
for (int i = 0; i < s.size(); ++i) {
t += s[i];
t += "#";
}
// Process t
vector<int> p(t.size(), 0);
int mx = 0, id = 0, resLen = 0, resCenter = 0;
for (int i = 1; i < t.size(); ++i) {
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
while (t[i + p[i]] == t[i - p[i]]) ++p[i];
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
if (resLen < p[i]) {
resLen = p[i];
resCenter = i;
}
}
return s.substr((resCenter - resLen) / 2, resLen - 1);
}
};
测试
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Solution {
public:
string longestPalindrome(string s)
{
int center = 0, length = 0, center1 = 0, length1 = 0;
for (int i=0;i<s.size();i++)
{
int count = 0;
while(i-count>=0&&i+count<s.size())
{
if (s[i-count] != s[i+count])
break;
count++;
}
count--;
center = count>length?i:center;
length = count>length?count:length;
count = 0;
while(i-count>=0&&i+1+count<s.size())
{
if (s[i-count] != s[i+1+count])
break;
count++;
}
center1 = count>length1?i:center1;
length1 = count>length1?count:length1;
}
return 2*length+1>2*length1?s.substr(center-length, 2*length+1):s.substr(center1-length1+1, 2*length1);
}
};
class Solution2 {
public:
string longestPalindrome(string s)
{
int left = 0, length = 0;
//vector<vector<int> > p(s.size(), vector<int> (s.size(), false));
int **p = new int* [s.size()];
for (int i = 0; i < s.size(); ++i)
{
p[i] = new int[s.size()];
}
for (int i = 0; i < s.size(); ++i)
{
for (int j = 0; j < s.size(); ++j)
{
p[i][j] = false;
}
}
for (int j=0;j<s.size();j++)//注意i j下标以及起始 范围
{
for(int i=0;i<=j;i++)
{
if (i == j)
p[i][j] = true;
if(j == i+1)
p[i][j] = s[i] == s[j];
if (j>i+1)
p[i][j] = s[i] == s[j]&&p[i+1][j-1];
if(p[i][j]&&j-i+1>length)
{
left = i;
length = j-i+1;
}
}
}
return s.substr(left, length);
}
};
class Solution1 {
public:
string longestPalindrome(string s) {
// Insert '#' 这样不用区分acca和aca两种情况
string t = "$#";
for (int i = 0; i < s.size(); ++i) {
t += s[i];
t += "#";
}
// Process t
vector<int> p(t.size(), 0);
int mx = 0, id = 0, resLen = 0, resCenter = 0;
for (int i = 1; i < t.size(); ++i) {
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
while (t[i + p[i]] == t[i - p[i]]) ++p[i];
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
if (resLen < p[i]) {
resLen = p[i];
resCenter = i;
}
}
return s.substr((resCenter - resLen) / 2, resLen - 1);
}
};
int main()
{
Solution s;
Solution1 s1;
string ss("abccbasdfsqwerdrewq");
string res = s.longestPalindrome(ss);
string res1 = s1.longestPalindrome(ss);
cout<<res<<endl;
cout<<res1<<endl;
}