Leetcode--最長迴文子串

/**
 * 給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲 1000。
 * <p>
 * 示例 1:
 * <p>
 * 輸入: "babad"
 * 輸出: "bab"
 * 注意: "aba" 也是一個有效答案。
 * 示例 2:
 * <p>
 * 輸入: "cbbd"
 * 輸出: "bb"
 *
 **/
public class 最長迴文子串 {


    /**
     * 首先這類問題通過窮舉的辦法,判斷是否是迴文子串並再篩選出最長的,效率是很差的。我們使用 動態規劃 的策略來求解它。
     * 首先我們從子問題入手,並將子問題的解保存起來,然後在求解後面的問題時,反覆的利用子問題的解,可以極大的提示效率。
     *
     * 由於最長迴文子串是要求連續的,所以我們可以假設 j 爲子串的起始座標,i 爲子串的終點座標,其中 i 和 j 都是大於等於
     * 0 並且小於字符串長度 length 的,且 j <= i,這樣子串的長度就可以使用 i - j + 1 表示了。
     *
     * 我們從長度爲 1 的子串依次遍歷,長度爲 1 的子串肯定是迴文的,其長度就是 1;然後是長度爲 2 的子串依次遍歷,只要
     * str[i] 等於 str[j] ,它就是迴文的,其長度爲 2;接下來就好辦了,長度大於 2 的子串,如果它要滿足是迴文子串的性質
     * ,就必須有 str[i] 等於 str[j] ,並且去掉兩頭的子串 str[j+1 ... i-1] 也一定是迴文子串,所以我們使用一個數組來
     * 保存以 j 爲子串起始座標,i 爲子串終點座標的子串是否是迴文的,由於我們是從子問題依次增大求解的,所以求解 [i ... j]
     * 的問題時,比它規模更小的問題結果都是可以直接使用的了。

     * @return
     */
    public static String getLPS(String s) {
        char[] chars = s.toCharArray();
        int length = chars.length;
        boolean[][] lps = new boolean[length][length];
        //記錄最長迴文子串最長長度
        int maxLen = 0;
        // 記錄最長迴文子串的起始位置
        int start = 0;
        for (int i=0; i< length; i++) {
            for (int j=0; j<=i; j++) {
                if (i - j < 2) {
                    lps[j][i] = chars[i] == chars[j];
                } else {
                    lps[j][i] = lps[j+1][i-1] && (chars[i]== chars[j]);
                }
                if (lps[j][i] && (i-j+1) >maxLen) {
                    maxLen = i -j +1;
                    start = j;
                }
            }
        }
        return s.substring(start,start+maxLen);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章