214. Shortest Palindrome

来源:互联网 发布:怎样委托网络投资理财 编辑:程序博客网 时间:2024/05/22 08:15

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


Solution:

First reverse the string abcd -> dcba

then compare two strings find the longest substring that is the prefix of s and the suffix of s.reverse()

Shift to match and add together

         abcd

+ dcba

---------------

   dcbabcd


Code:

public class Solution {    public String shortestPalindrome(String s) {        String rev = new StringBuilder(s).reverse().toString();        for(int i = 0 ; i < s.length(); i++){            if(rev.substring(i).equals(s.substring(0,s.length() - i))){                return rev.substring(0,i) + s;            }        }                return rev + s;            }}

This will get TLE since it took O(n2) to find the common prefix/suffix.

Using KMP to find the prefix suffix is much faster, taking O(n) time

First we build the string s + "#" + s.reverse().

a b c d # d c b a

and the kmp table should be:

a b c d # d c b a

0 0 0 0 0 0 0 0 1

return dcbabcd

the number in the table means the length of the common prefix/suffix ends at that position


Another example

a  a  c  e  c  a  a  a  #  a  a  a  c  e  c  a  a

0  1  0  0  0  1  2  2  0  1  2  2  3  4  5  6  7

so the anwser is a + a  a  c  e  c  a  a  a = aaacecaaa


How to compute this table?

public int[] computeKMP(String p){        int[] ret = new int[p.length()];        int j = 0;        int i = 1;        while(i < p.length()){            if(p.charAt(j) == p.charAt(i)){                ret[i] = j + 1;                j++;                i++;            } else {                if(j == 0){                    ret[i] = 0;                    i++;                } else{                    j = ret[j - 1];                }            }        }        return ret;    }

And the code:

public String shortestPalindrome(String s) {        String rev = new StringBuilder(s).reverse().toString();        String p = s + "#" + rev;        int[] kmp = computeKMP(p);        int len = kmp[kmp.length - 1];                return new StringBuilder(s.substring(len)).reverse().toString() + s;        }












0 0
原创粉丝点击