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);
    }
}

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