演算法之字串——最長迴文子串

it_was發表於2020-10-02

難度中等:smirk:
給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。

眾所周知,迴文子串是以某一軸為中心,左右呈映象對稱,如何找到 s 中最長的迴文子串呢?

暴力破解是最容易想到的一種解法,即以每個字元為中心,向左右兩邊擴,看擴出去的範圍有多大,同時記錄一個最大值。比如 s = "abhba",最大回文子串即以 字元 h 為中心,左右擴到底。然而這種方法有個問題,無法應對偶迴文:cold_sweat:,當 s ="abba"的時候,以每個字元為中心擴結果得到的最長迴文子串長度為 1 !明顯是錯誤的!
所以為了解決上述無法應對偶迴文的情況,需要引入特殊字元來解決,即在每一個字元左右新增上一個特殊字元進行佔位:smiley:,這樣就可以解決這個問題
上述的 s ="abba" 就變成了 s ="#a#b#b#a#",這樣我們就可以通過暴力法解決!

以下為暴力法的程式碼

public char[] getSPString(String s){
        int len = s.length();
        char[] arr = new char[2 * len + 1];
        for(int i = 0 ;i < len;i++){
            arr[2 * i] = '#';
            arr[2 * i + 1] = s.charAt(i);
        }
        arr[2 * len] = '#';
        return  arr;
    }
    public String longestPalindrome(String s) {
        if(s == null || s.length() <= 1){
            return s;
        }
        char[] res = getSPString(s);
        int len = res.length;
        int C = 0;   //最長迴文串中心
        int max = 1;  //最長迴文串長度

        for(int i = 0; i< len;i++){
            int j = 1;
            while(i - j >=0 && j + i < len){
                if(res[i - j] ==  res[i + j]){
                    j++;
                }else{
                    break;
                }
            }
            if(2 * j - 1 > max){
                C = i;
                max = 2 * j - 1;
            }   
        }
        return s.substring((C - max/2)/2 , (C+ max/2)/2);
    }

演算法之字串——最長迴文子串

*暴力法的缺點在於,最壞情況下時間複雜度趨近於 O(n^2)! *

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章