题目链接
Longest Palindromic Substring - LeetCode
注意点
- 回文串长度至少为1
解法
解法一:将一个字符定为回文串的中心字符,向两边扩展寻找最长回文串。要根据回文串长度要分为奇偶两种情况考虑,如果长度是奇的情况,两边扩展即可,例如“mon”字符o就是中心。如果长度是偶数,例如“moon”字符串oo才是中心,右边界要跳过重复的字符。时间复杂度为O(n^2)
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() < 2)
{
return s;
}
int i,n = s.size(),maxlen = 0,start;
for(i = 0;i < n;i++)
{
if(n - i < maxlen/2)
{
break;
}
int left = i,right = i;
while(right < n && s[right] == s[right+1])
{
right++;
}
while(left > 0&&right < n-1&&s[left-1] == s[right+1])
{
left--;
right++;
}
if((right-left+1)>maxlen)
{
maxlen = (right-left+1);
start = left;
}
}
return s.substr(start,maxlen);
}
};
解法二:动态规划,P[i,j]表示S[i]到S[j]之间的串是否为回文串。递推式如图: 时间复杂度O(n^2)
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() < 2)
{
return s;
}
int i,j,n = s.size(),maxlen = 1;
int dp[n][n] = {0},start = 0;
for(j = 0;j < n;j++)
{
for(i = 0;i < j;i++)
{
if(j - i == 0)
{
dp[i][j] = 1;
}
else if(j - i == 1)
{
dp[i][j] = (s[i]==s[j]);
}
else
{
dp[i][j] = (s[i]==s[j])&&dp[i+1][j-1];
}
if(dp[i][j] == 1 && maxlen < j-i+1)
{
maxlen = j-i+1;
start = i;
}
}
dp[j][j] = 1;
}
return s.substr(start,maxlen);
}
};
解法三:就是著名的马拉车算法,时间复杂度为O(n)
小结
- 马拉车算法非常巧妙,还要多花点时间钻研。