欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode最长回文子串

程序员文章站 2022-07-13 23:25:30
...

题目来源

leetcode最长回文子串

解题方法

动态规划

dp[i,j]其中i,j表示子串的首尾,一个长度的子串一定是回文的,两个长度的且相等字母的子串也一定是回问的,于是dp[i][i]=1,dp[i][i+1]=1

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        if(n==0 || n==1)
            return s;
        int start=0;//记录子串的起始位置
        int max=1;//记录子串最大长度
        vector<vector<int>> dp(n, vector<int>(n));
        for(int i=0;i<n;i++){
            dp[i][i]=1;
            if(i+1<n && s[i] == s[i+1]){
                dp[i][i+1]=1;
                max=2;
                start=i;
            }
        }
        for(int l=3;l<=n;l++){ // l是要处理的子串长度,从3开始
            for(int i=0;i+l-1<n;i++){
                int j = i+l-1;// 终止位置
                if(s[i]==s[j]&&dp[i+1][j-1]){
                    dp[i][j]=1;
                    max=l;
                    start=i;
                }
            }
        }
        return s.substr(start, max);
    }
};

中心展开法

对于每个字符,可以以单个字符展开,若与后一个字符相等,也可以将其和后面一个字符展开,判断最大的长度

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        if(n==0 || n==1)
            return s;
        int start=0;//记录子串的起始位置
        int end=0; //记录子串的结束位置
        int mLen=1;//记录子串最大长度
        for(int i=0;i<n;i++){
            int len1=helper(s,i,i);// 以一个点为中心展开
            int len2=helper(s,i,i+1);// 以两个点为中心展开
            mLen=max(max(len1,len2),mLen);
            if(mLen > end-start+1){
                start=i-(mLen-1)/2;
                end=i+mLen/2;
            }
        }
        cout << mLen;
        return s.substr(start, mLen);
    }
    int helper(string s, int left, int right){
        int L=left;
        int R=right;
        while(L>=0 && R<s.size() && s[L]==s[R]){
            L--;
            R++;
        }
        return R-L-1;
    }
};