5. 最长回文子串(动归/中心扩展法)

Posted Ston.V

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5. 最长回文子串(动归/中心扩展法)相关的知识,希望对你有一定的参考价值。

1.Description

给你一个字符串 s,找到 s 中最长的回文子串。

2.Example

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:

输入:s = "cbbd"
输出:"bb"

3.My code(Not AC,timeout)

暴力求解

class Solution 
public:

    bool isCircle(string s)
        for(int i=0;i<s.length()/2;i++)
            if(s[i]!=s[s.length()-1-i])
                return false;
        
        return true;
    

    string longestPalindrome(string s) 
        int len =0;
        string res="";
        for(int i=0;i<s.length();i++)
            for(int j=1;j<=s.length()-i;j++)
                string tmp = s.substr(i,j);
                if(isCircle(tmp) && tmp.length()>len)
                    len = tmp.length();
                    res = tmp;
                
            
        
        return res;
    
;

4.Code(动态规划)

动态规划,状态转移方程为(如果[i,j]是回文串,那么只有s[i-1]==s[j+1]时,[i-1,j+1]才也是回文串):

初始条件为(当长度为1和2时,直接判断):

 

 错误写法:直接遍历i,j无法得到正确结果!!!!!!

比如当你求dp[0][3]时,你连dp[1][2]都没有开始求,因此无法递推到正确结果;需要使用步长来循环,然后才能开始递推。你得懂你递推的是什么啊!!!

class Solution 
public:

    string longestPalindrome(string s) 
        int n = s.length();
        //动归矩阵
        vector<vector<bool>> dp(n,vector<bool>(n));
        if(n<2)
            return s;
        
        //初始化
        for(int i=0;i<n;i++)
            dp[i][i]= true;
        
        int len=1;
        string res=s.substr(0,1);
            
        //遍历二维数组
        for(int i=0;i<n;i++)
            for(int j=i+1;j<n;j++)
                if(s[i] != s[j])
                    dp[i][j]=false;
                else
                    if(j-i+1<=2)
                        dp[i][j]=true;
                    else
                        dp[i][j]=dp[i+1][j-1];
                
                if(dp[i][j] && j-i+1>len)
                    len = j-i+1;
                    res = s.substr(i,j-i+1);
                
            
        return res;      
    
;

正确code:需要使用步长来递推

class Solution 
public:

    string longestPalindrome(string s) 
        int n = s.length();
        //动归矩阵
        vector<vector<bool>> dp(n,vector<bool>(n));
        if(n<2)
            return s;
        
        //初始化
        for(int i=0;i<n;i++)
            dp[i][i]= true;
        
        int len=1;
        string res=s.substr(0,1);
            
        //依步长递推
        for(int step=1;step<=n;step++)
            for(int i=0;i<n;i++)
                int j = i+step-1;
                if(j>=n)
                    break;
                if(s[i]==s[j])
                    if(step<=2)
                        dp[i][j]=true;
                    else
                        dp[i][j]=dp[i+1][j-1];
                else
                    dp[i][j]=false;

                if(dp[i][j] && step>len)
                    len = step;
                    res = s.substr(i,step);
                
            
        
        return res;      
    
;

5.思路

1.动归你得看看你这是靠什么在递推,这里直接双层for i,j是递推不出来的

2.注意这里的边界是串长为1或2,在递推中判断长为2的情况

3.中心扩展法(容易理解):

我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。

class Solution 
public:
    pair<int, int> expandAroundCenter(const string& s, int left, int right) 
        while (left >= 0 && right < s.size() && s[left] == s[right]) 
            --left;
            ++right;
        
        return left + 1, right - 1;
    

    string longestPalindrome(string s) 
        int start = 0, end = 0;
        for (int i = 0; i < s.size(); ++i) 
            auto [left1, right1] = expandAroundCenter(s, i, i);
            auto [left2, right2] = expandAroundCenter(s, i, i + 1);
            if (right1 - left1 > end - start) 
                start = left1;
                end = right1;
            
            if (right2 - left2 > end - start) 
                start = left2;
                end = right2;
            
        
        return s.substr(start, end - start + 1);
    
;

以上是关于5. 最长回文子串(动归/中心扩展法)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 5. 最长回文子串

LeetCode 5. 最长回文子串

小Y学算法⚡️每日LeetCode打卡⚡️——5.最长回文子串

算法提升——中心扩散法(最长回文子串和回文子串)

最长回文子串(动规,中心扩散法,Manacher算法)

2021/5/24回文子串与中心扩展法动态规划法