您的位置:首页 > 其它

【LeetCode】5. Longest Palindromic Substring

2017-06-20 23:04 260 查看

5. 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.

Example:

Input: "babad"

Output: "bab"

Note: "aba" is also a valid answer.


Example:

Input: "cbbd"

Output: "bb"


解答

方法1: 动态规划

利用一个辅助数组help,help[i][j]记录着子字符串s[i]~s[j]是否是回文。如果是回文则为1,不是回文则为0.

所以递推关系式是:
1  s[i] == s[j] 且 help[i+1][j-1] == 1
help[i][j] =    1  s[i] == s[j] 且 j == i+1
0  其他


在自下而上填写动态规划数组的时候,我们记录下最长的回文子字符串就可以了。

class Solution {
public:
// 最长回文子字符串
// 做法1:用DP做 时间复杂度 O(N^2),空间复杂度O(N^2)
string longestPalindrome(string s) {
if(s.size() <= 1)  return s;
vector<vector<int>> help(s.size(),vector<int>(s.size(),1));

int maxSize = 1;
string res = s.substr(0,1);

for(int i = 0; i < s.size(); ++i)
help[i][i] == 1;

for(int i = s.size()-1; i >= 0; --i)
{
for(int j = i+1; j < s.size(); ++j)
{
help[i][j] = ((s[i] == s[j]) && (help[i+1][j-1]));
if(help[i][j] && j-i+1 > maxSize)
{
maxSize = j-i+1;
res = s.substr(i,maxSize);
}
}
}
return res;
}
};


方法2

对于回文子字符串的回文序列一定存在一个对称轴,沿着对称轴两边扩展是完全相同的。

对于奇数个数的回文序列,对称轴一定在最中间节点。如
aba
的对称轴就是
a


对于偶数个数的回文序列,对称轴一定是在中间的两个节点。如
abba
的对称轴就是
bb
,并且两个节点的值也是相同的。

我们就是先确定可能的回文子字符串的中心点,然后往两端扩展,求取以此中心点的最长回文子字符串。按照回文子字符串的奇偶性不同,共有N-1+N = 2N-1个中心店。从这些中心点展开寻找最长的回文子字符串即可。

时间复杂度为O(N^2)。

class Solution {
public:
string longestPalindrome(string s)
{
if(s.size() <= 1)   return s;

int maxSize = 1;
string res = s.substr(0,1);

for(int i = 0; i < s.size()-1; ++i)
{
string temp = getPalindrome(s,i,i);
if(temp.size() > res.size())
res = temp;
temp = getPalindrome(s,i,i+1);
if(temp.size() > res.size())
res = temp;
}
string temp = getPalindrome(s,s.size()-1,s.size()-1);
if(temp.size() > res.size())
res = temp;
return res;
}
private:
string getPalindrome(string s,int left,int right)
{
while(left >= 0 && right < s.size() &&  s[left] == s[right])
{
--left,++right;
}
return s.substr(left+1,right-left-1);
}
};


方法3

方法3十分巧妙,它是确保先寻找可能的回文中心,然后再往两端扩展,查找相应的回文子字符串。时间复杂度应该为O(N)~O(N^2)

class Solution {
public:
// 做法3:时间复杂度为O(N) ~ O(N^2), 3ms
string longestPalindrome(string s)
{
if(s.size() <= 1)   return s;
int min_start = 0, max_len = 1;
for(int i = 0; i < s.size(); )
{
int j = i, k = i;
while(k < s.size()-1 && s[k+1] == s[k])     {++k;}    //跳过重复元素
i = k+1;
while(j > 0 && k < s.size()-1 && s[j-1] == s[k+1])     {--j,++k;}
int new_len = k-j+1;
if(new_len > max_len)
{
min_start = j;
max_len = new_len;
}
}
return s.substr(min_start,max_len);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string leetcode