Leetcode#5 最長迴文子串

算法題目:

給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲 1000。

示例 1:
輸入: “babad”
輸出: “bab”
注意: “aba” 也是一個有效答案。

示例 2:
輸入: “cbbd”
輸出: “bb”

算法思路:

觀察迴文串的特點,其必定以某字符爲中心完全對稱,如:"abba"以"bb"爲中心對稱,"aba"以"b"爲中心對稱,"abba"以"bb"爲中心對稱,"abbba"以"bbb"爲中心對稱。
故我們只需遍歷以所有字符(or 多個相連重複字符)爲中心的子串(遍歷時可將多個相連重複字符視爲一箇中心字符),並判定其是否爲迴文串,若是迴文串,則將其長度與以前一字符爲中心時的最大長度max_len進行比較,長度更大則更新max_len,長度更小則保留原來的max_len。用left和right記錄以s[index]爲中心的迴文子串的最左端和最右端,因此迴文子串長度爲 (right - 1) - (left + 1) + 1 = right-left-1。

算法步驟如下:
1)從index=0開始遍歷字符串,用left和right記錄以s[index]爲中心的迴文子串的最左端和最右端,left=index-1,right=index+1;
2)以index爲起始位置向右計數所有與s[index]相等且連續的字符,若有多個相等連續字符則以多個相等字符爲中心,right指向中心字符串的下一個字符,而left指向中心字符串的前一個字符。若僅以一個字符爲中心,則left和right不變。循環執行4);
3)定位下一個中心index,下一個中心爲單個字符或重複字符串的下一個字符。
4)比較s[left]與s[right],若相等則left–,right++,直至兩者不相等或left與right超出索引範圍循環結束,更新max_len的值,並記錄該子串的開始位置start=left+1。

代碼實現:

class Solution {
public:
    string longestPalindrome(string s) {
        if(s == "") return "";
        int start = 0;
        int left = 0;
        int right = 0;
        int max_len = 0;
        int index = 0;
        while(s[index]){
            right = index + 1;
            left = index - 1;
            //從當前字符開始往右讀取連續重複字符
            //(連續重複字符必定能構成迴文子串,也必定是迴文子串的一部分)
            //如"abbaa" 中從索引1開始的連續重複字符是"bb",從索引3開始連續重複字符是'aa'
            while(s[right] == s[index]){
                right ++;
            }
            //定位下一個子串的中心
            index = right;
            while(left >= 0 && right <= s.size() && s[left] == s[right]){
                left --;
                right ++;
            }
            if(right - left - 1 > max_len){
                start = left + 1;
                max_len = right - left - 1;
            }
        }
        return s.substr(start, max_len);
    }
};

運行結果:

#5result

發佈了33 篇原創文章 · 獲贊 28 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章