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".

 

 

构造最短的回文串。

 

 

1、自己写的暴力的方法:从中间向做判断,是否以pos为中点、word[0]为左边界构成回文串,如果是,那么返回结果即可。通过,但是很慢。

public class Solution {
    public String shortestPalindrome(String s) {
        
        int len = s.length();
        if (len < 2){
            return s;
        }
        char[] word = s.toCharArray();
        if (len % 2 != 0){
            if (isParlindrome(word, len / 2, false)){
                return s;
            }
        }
        int pos = len / 2 - 1;
        boolean isMid = false;
        for (; pos >= 0; pos--){
            if (isParlindrome(word, pos, true)){
                isMid = true;
                break;
            }
            if (isParlindrome(word, pos, false)){
                break;
            }
        }
        char[] newWord;
        if (isMid == true){
            newWord = new char[len + len - pos * 2 - 2];
        } else {
            newWord = new char[len + len - pos * 2 - 1];
        }
        for (int i = 0, j = 0; i < newWord.length - len; i++, j++){
            newWord[j] = word[len - 1 - j];
        }
        for (int i = 0, j = newWord.length - len; i < len; i++, j++){
            newWord[j] = word[i];
        }
        return String.valueOf(newWord);
    }
    
    public boolean isParlindrome(char[] s, int mid, boolean isMid){
        
        int left = mid - 1;
        if (isMid == true){
            left = mid;
        }
        int right = mid + 1;
        while (left >= 0 && s[left] == s[right]){
            left--;
            right++;
        }
        if (left == -1){
            return true;
        } else {
            return false;
        }
    }
    
    
}

 

 

2、利用KMP算法。参考discuss

//S is the pattern to be preprocessed
//output[i] is the failure index that output redirected to
public static int[] KMPpreprocess(String S){
    int[] pi=new int[S.length()];
    //init start of pi
    pi[0]=-1;
    //get each index in pi, i is the index being processed
    for (int i=1;i<pi.length;i++){
        int j=pi[i-1];
        while (j!=-1 && S.charAt(j+1)!=S.charAt(i)) {j=pi[j];}
        if (j==-1){
            if (S.charAt(0)==S.charAt(i)) pi[i]=0;
            else pi[i]=-1;
        }
        else if (S.charAt(j+1)==S.charAt(i)){
            pi[i]=j+1;
        }
        
    }
    
    return pi;
}

public static String reverse(String s){
    char[] outC=new char[s.length()];
    for (int i=0;i<outC.length;i++){
        outC[i]=s.charAt(outC.length-1-i);
    }
    return new String(outC);
}

public static String shortestPalindrome(String s) {
    String sPlus=s+"#"+reverse(s);
    int[] PI=KMPpreprocess(sPlus);
    int palinIndex=Math.min(PI[PI.length-1],s.length()-1);
    
    String nonPalin=s.substring(palinIndex+1);
    String Palin=s.substring(0,palinIndex+1);
    return reverse(nonPalin)+Palin+nonPalin;
}