LeetCode-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”

解法一:
以字符串中的每一个字符为中心向两边开始遍历,找到最长回文字符串,注意分奇偶两种情况。复杂度O(N^2)

class Solution {
public:
    string longestPalindrome(string s) {
        int n=s.size();
        if(n==0 || n==1)return s;
        int i,l,r,k,curr_len,max_len=1;
        l=r=0;
        for(i=0;i<n;i++){
            if(s[i]==s[i+1]){
                curr_len=2;
                k=1;
                while((i-k)>=0 && (i+k+1)<n && s[i-k]==s[i+k+1]){
                    k++;
                    curr_len+=2;
                }
                if(curr_len>max_len){
                    max_len=curr_len;
                    l=i-k+1;
                    r=i+k;
                }
            }
            if(i>0){
                if(s[i-1]==s[i+1]){
                    curr_len=3;
                    k=2;
                    while((i-k)>=0 && (i+k)<n && s[i-k]==s[i+k]){
                        k++;
                        curr_len+=2;
                    }
                    if(curr_len>max_len){
                        max_len=curr_len;
                        l=i-k+1;
                        r=i+k-1;
                    }
                }
            }
        }
        return s.substr(l,r-l+1);
    }
};
//或者用函数实现(思路上更简单)
string expandAroundCenter(string s,int c1,int c2){
    int l=c1,r=c2;
    int n=s.length();
    while(l>=0 && r<=n && s[l]==s[r]){
        l--;
        r++;
    }
    return s.substr(l+1,r-l-1);
}
class Solution{
public:
    string longestPalindrome(string s){
        int n=s.size();
        if(n==0 || n==1)return s;
        string longest=s.substr(0,1);
        for(int i=0;i<n-1;i++){
            string p1=expandAroundCenter(s,i,i);
            if(p1.size()>longest.size())longest=p1;
        string p2=expandAroundCenter(s,i,i+1);
        if(p2.size()>longest.size())longest=p2;
        }
        return longest;
    }
}

解法二:
动态规划,复杂度O(N^2),见图示,dp[j][i]表示区间[j,i]是否为回文串,是则为1,否则为0,当i==j时,肯定为1,i=j+1时,若s[i]==[j],则为1,当i-j>=2时,除了判断s[j]==s[i]还需dp[j+1][i-1]==1,也即:
dp[j][i]=1, if i==j;
dp[j][i]=(s[j]==s[i]), if j=i+1;
dp[j][i]=(s[j]==s[i] && dp[i+1][j-1]), if j>i+1

这里写图片描述

class Solution{
public:
    string longestPalindrome(string s){
        int n=s.size();
        vector<vector<int>> dp(n,vector<int>(n,0));
        int left=0,right=0,len=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                dp[j][i]=(s[i]==s[j] && (i-j==1 || dp[j+1][i-1]));
                if(dp[j][i] && len < i-j+1){
                    len=i-j+1;
                    left=j;
                    right=i;
                }
            }
            dp[i][i]=1;
        }
        return s.substr(left,right-left+1);
    }
}

解法三:
马拉车算法:Manacher’s Algorithm,复杂度O(N),如图:
这里写图片描述
可参考博客:
http://www.cnblogs.com/grandyang/p/4475985.html
http://blog.csdn.net/dyx404514/article/details/42061017(个人认为这篇博客更加简单易懂)

class Solution{
public:
    string longestPalindrome(string s){
        string t ="$#";
        for(int i=0;i<s.size();i++){
            t+=s[i];
            t+='#';
        }
        vector<int> p(t.size(),0);
        int id=0,mx=0,resId=0,resMx=0;
        for(int i=0;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(resMx<p[i]){
                resMx=p[i];
                resId=i;
            }
        }
        return s.substr((resId-resMx)/2,resMx-1);
    }
}
posted @ 2022-11-20 22:40  风一样的liz  阅读(24)  评论(0编辑  收藏  举报