代码重构:leetcode 5. 最长回文子串

120 阅读1分钟

5. 最长回文子串

没什么特别的,就是马拉车算法。

关于马拉车算法,dp[i]是半径,除i这点的半径,于是最后会得到的结果是:

int start = (index-MAX)/2;
s.substring(start,start+MAX);

原因是最后最长的半径比如从#开始,于是最后长度就是dp[index],而起点必然减半

   public String longestPalindrome(String s) {
        return manacher(s);
    }

    //返回^开头 $结尾
    public String preSolve(String s) {
        StringBuilder builder = new StringBuilder();
        builder.append('^');
        for (int i = 0; i < s.length(); i++) {
            builder.append("#").append(s.charAt(i));
        }
        builder.append('#');
        builder.append('$');
        return builder.toString();
    }

    public String manacher(String s) {
        String t = preSolve(s);
        int[] dp = new int[t.length()];
        int border = 1, mid = 1;
        int index = -1, MAX = -1;
        for (int i = 1; i < t.length() - 1; i++) {
            int minn = 0;
            if (i < border) {
                int j = 2 * mid - i;
                minn = Math.min(border - i, dp[j]);
            }
            while (t.charAt(i + minn) == t.charAt(i - minn)) minn++;
            dp[i] = minn - 1;
            if (i + dp[i] > border) {
                border = i + dp[i];
                mid = i;
            }
            if (dp[i] > MAX) {
                MAX = dp[i];
                index = i;
            }
        }
        int start = (index-MAX)/2;
        return s.substring(start,start+MAX);
    }