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"
解题思路:问题是要求最长的回文串,并返回这个子串.一种思路是动态规划,(就是我的思路),O(n^2) 89ms AC,有注释,很好想到;另一种就是大佬提供的思路,从头开始以每个字符为中心向两边扩散,并附带一些优化.最后达到O(n) 6ms AC.
其实我认为,就算不优化,针对以每个字符为中心位置扩散,只要考虑ABA和ABBA两种情况,然后对长度做一个小优化,性能应该也不错吧.事实证明,9ms AC.
下面附上三种代码,按照上面叙述的顺序.
class Solution {
public:
string longestPalindrome(string s) {
//dp[i][j] 表示 s[i,j] 是否是一个回文串。 dp[i][j] = (s[i]==s[j] && dp[i+1][j-1])
int len = s.length(), MaxLen = 1, left = 0;
bool dp[1100][1100]={};
if(s.length() == 0)
return "";
else if(s.length() == 1)
return s;
for(int i=0;i<len;i++)
dp[i][i] = true;
for(int i=len-1;i>=0;i--)
{
for(int j=i+1;j<len;j++)
{
dp[i][j] = ((s[i]==s[j])&&(dp[i+1][j-1] || j==i+1));
if(dp[i][j])
{
if(j-i+1 > MaxLen)
{
MaxLen = j-i+1;
left = i;
}
}
}
}
return s.substr(left,MaxLen);
}
};
class Solution {
public:
string longestPalindrome(string s) {
if (s.length() < 2)
return s;
int len = s.size(), max_left = 0, max_len = 1, left, right;
for (int start = 0; start<len && len-start>max_len/2 && start+1>max_len/2;)
{
//从中心向两端扩散
left = start;
right = start;
while (right < len - 1 && s[right + 1] == s[right])
right++;
start = right + 1;
while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
{
right++;
left--;
}
if (max_len < right - left + 1)
{
max_left = left;
max_len = right - left + 1;
}
}
return s.substr(max_left, max_len);
}
};
class Solution {
public:
string longestPalindrome(string s) {
if (s.length() < 2)
return s;
int len = s.size(), max_left = 0, max_len = 1, left, right;
for (int start = 0; start<len && len-start>max_len/2 && start+1>max_len/2;start++)
{
//从中心向两端扩散
left = start;
right = start;
while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
{
right++;
left--;
}
if (max_len < right - left + 1)
{
max_left = left;
max_len = right - left + 1;
}
left = start;
right = start+1;
if(s[left] == s[right])
{
while (right<len-1 && left>0 && s[right + 1]==s[left - 1])
{
right++;
left--;
}
if (max_len < right - left + 1)
{
max_left = left;
max_len = right - left + 1;
}
}
}
return s.substr(max_left, max_len);
}
};