Shortest Palindrome
Total Accepted: 18753 Total Submissions: 95420 Difficulty: Hard
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
For example:
Given "aacecaaa", return "aaacecaaa".
Given "abcd", return "dcbabcd".
思路
- step1 扩展点,每个点有个空格
- step2 找每个点周围最多相等的点的数量
- step3 找最大的数量
- step4 找最大数量的点
- step5 extend stringbuilder
- step6 combine
- O(n2)
- leetcode超时,IDE能跑出来
public class Solution {
    public String shortestPalindrome(String s) {
        if (s == null || s.equals("")) {
            return new String();
        }
        int size = s.length();
        int newLen = size * 2;
        char[] chars = new char[newLen];
        chars[0] = ' ';
        for (int i = 0; i < size - 1; i++) {
            chars[2 * i + 1] = s.charAt(i);
            chars[2 * i + 2] = ' ';
        }
        chars[size * 2 - 1] = s.charAt(size - 1);
        int[] nums = new int[newLen];
        for (int i = 1; i < newLen - 1; i++) {
            for (int len = 1; i + len < newLen && i - len >= 0; len++) {
                char before = chars[i - len];
                char after = chars[i + len];
                if (before == after) {
                    nums[i] = nums[i] + 1;
                } else {
                    break;
                }
            }
        }
        nums[0] = 1;
        int max = 0;
        for (int i = 0; i < newLen; i++) {
            if (nums[i] > max) {
                max = nums[i];
            }
        }
        int index = 0;
        for (int i = 0; i < newLen; i++) {
            if (nums[i] == max) {
                index = i;
                break;
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i = newLen - 1; i > index + max; i--) {
            if (chars[i] != ' ') {
                sb.append(chars[i]);
            }
        }
        return sb.toString() + s;
    }
}
O(n) KMP
public class Solution {
    public String shortestPalindrome(String s) {
        int j = 0;
        for (int i = s.length() - 1; i >= 0; i--) {
           if (s.charAt(i) == s.charAt(j)) {
               j += 1;
           }
        }
        if (j == s.length()) {  
            return s;
        }
        String suffix = s.substring(j); 
        String prefix = new StringBuilder(suffix).reverse().toString(); 
        String mid = shortestPalindrome(s.substring(0, j)); 
        String ans = prefix + mid  + suffix;
        return  ans;
    }
}