【leetcode 5. 最長迴文子串】解題報告

方法一:中心擴展算法算法

解題思路:從左到右每個字符都做爲中心軸,而後逐漸往兩邊擴展,只要發現有不相等的字符,則肯定了以該字符爲軸的最長迴文串,但須要考慮長度爲奇數和偶數的不一樣狀況的處理(長度爲偶數時軸心爲中間兩個數的中心,長度爲奇數時軸心爲中間那個數)spa

算法時間複雜度:$O(n^{2})$code

    string longestPalindrome(string s) {        
        int idx = 0, maxL = 0;
        for (int i = 0; i < s.size(); ++i)  // i爲軸的位置,j爲迴文串半徑
        {
            for (int j = 0; i - j >= 0 && i + j < s.size(); ++j)    // 奇數
            {
                if (s[i - j] != s[i + j])
                    break;
                if (2 * j + 1 > maxL)
                {
                    maxL = 2 * j + 1;
                    idx = i - j;
                }
            }
            for (int j = 0; i - j >= 0 && i + j + 1 < s.size(); ++j)    // 偶數
            {
                if (s[i-j]!=s[i+j+1])
                    break;
                if (2 * j + 2 > maxL)
                {
                    maxL = 2 * j + 2;
                    idx = i - j;
                }
            }
        }
        return s.substr(idx, maxL);
    }

方法二:manacher(馬拉車法)blog

解題思路:詳見P3805 【模板】manacher算法get

算法時間複雜度爲:$O(n)$string

    int pos[2005],p[2005];
    string longestPalindrome(string s) {        
        /* 填充字符,統一爲奇數串 */
        string s_new="~";
        for (int i=0,k=1;i<s.size();++i)
        {
            s_new+="#";
            s_new+=s[i];
            pos[k++]=i; // 記錄新字串與原始字串的位置關係
            pos[k++]=i;
        }
        s_new+="#";
        
        /* manacher */
        int m=0,r=0,maxL=0,idx=0;
        for (int i=1;i<s_new.size();++i)
        {
            // 獲取已知的最小回文半徑
            if (i<r)
                p[i]=min(p[2*m-i],r-i);
            else
                p[i]=1;
            // 暴力拓展左右兩側
            while (s_new[i-p[i]]==s_new[i+p[i]])
                p[i]++;
            // 新的迴文半徑比較大,則更新
            if (r-i<p[i])
            {
                m=i;
                r=i+p[i];
            }
            // 更新迴文長度(原始字串的迴文長度爲新字串迴文半徑-1)
            if (p[i]-1>maxL)
            {
                maxL=p[i]-1;
                idx=pos[i]-maxL/2;  // 更新原始迴文字串的起始位置
            }
        }
        return s.substr(idx,maxL);
    }
相關文章
相關標籤/搜索