0
点赞
收藏
分享

微信扫一扫

5. Longest Palindromic Substring

非常帅气的昵称吧 2022-03-18 阅读 106

一直觉得会非常难的题目,没有想到会如此简单。

既然要找最长的回文子串,那么是不是就只要找到合适的中心线,然后依次往外扩展。

比如abcba, 中心线为c的时候,依次往外扩展。就能找到最长的回文子串了那?

这样的话就转换为寻找中心线的问题了。

不过中心线不一定是在字母上,也有可能是在两个字母之间。

这样也能理解,找最长的回文子串。有可能是以中心字母开始往两边扩展。

也有可能是abba这样中间两个字母往外扩展。

所以两个不同的中心线的方法都要考虑。

一下就是代码了。

class Solution {
public:
    string getPalindronme(int start,int end,string s)
    {       
            while(start >=0 && end < s.length() && s[start] == s[end]) {
                start--;
                end++;
            }

            //跳出循环的唯一原因就是当前start 到 end 已经破坏了回文。返回前一个状态(已经是回文状态并取出字符)
            return s.substr(start+1, end-start-1);
        
    } 
        
    string longestPalindrome(string s) {
        //使用中心线算法去做这个题目。
        //但是中心线有两种, 以某个字母为中心向两边展开
        //2 以两个字母中间为中心线向两边展开。
        
        if(s.length() <2)
            return s;
        
        string longPalind = "";
        
        //go through each position to find the 中心线
        for(int i =0;i<s.length();i++) {
            //odd
            int start = i;
            int end = i;
            
            string curPalind = getPalindronme(start, end, s);
            if(curPalind.length() > longPalind.length())
                longPalind = curPalind;
            
            //even
            start = i;
            end = i+1;
            
            curPalind = getPalindronme(start, end, s);
            if(curPalind.length() > longPalind.length())
                longPalind = curPalind;
        }
        
        return longPalind;
    }
};

顺便带个DP的解法,生成一个二维数组。来记录i到j之间是否是回文。

这样来算出来最长的。

既然用DP,就得初始化矩阵。

首先,字母i到i 肯定是回文。

其次i到i+1可能判断是否是回文。

地推公式就是

[i][j] = [i+1][j-1] && s[i] == s[j]

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if(n<2)
            return s;
        int start=0;
        int longest=1;
        
        vector<vector<bool>> isPalindrome(n, vector<bool> (n, false));
        
        for(int i=0;i<n;i++) {
            isPalindrome[i][i] = true;
        }
        
        for(int i=0;i<n-1;i++){
                isPalindrome[i][i+1] = (s[i] == s[i+1]);
                if(isPalindrome[i][i+1] == true){
                    start =i;
                    longest = 2;
                }
        }
        
        for(int i=n-2;i>=0;i--) {
            for(int j=i+2;j<n;j++){
                isPalindrome[i][j] = isPalindrome[i+1][j-1] && (s[i] == s[j]);
                if(isPalindrome[i][j] == true) {
                    if(j-i+1 > longest) {
                        start = i;
                        longest = j-i+1;
                    }
                }    
            }
        }
        
        return s.substr(start, longest);
    }
};

举报

相关推荐

0 条评论