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.
Example 1:
Input: "aacecaaa"
Output: "aaacecaaa"
Example 2:
Input: "abcd"
Output: "dcbabcd"
Basic Idea:
在一个字符串前添加一段,使得其形成一个回文字符串,求最短的回文字符串。首先,如果将字符串s本身reverse之后接到前面,一定会形成一个回文串,那么如何让它尽可能短呢,就是要先找到从左端开始的最长回文串,然后只要将该最左边回文串右边的部分reverse后接在前面就可以了。如何 O(n) 时间内找到从最左边开始的最长回文串呢?我们可以将其reverse后接在最后,中间用特殊字符分隔,例如:abcbaggg -> abcbaggg#gggabcba,然后利用KMP算法的思路,求出KMP所需的next数组,我们就会得到 00001000000012345,则可知因为 next 数组最后一个数字为 5 ,说明以该位置结束的长度为5的substring和最左边的相同。由于#右部分是由s reverse而来,我们就得知了从 s 最左端开始的最长回文串长度为 5. 接下来只要复制 s.substring(5), reverse 之后接到前面就可以了。最终结果为 gggabcbaggg 。
Java Code:
classSolution{publicStringshortestPalindrome(Strings){String t = s +"#"+newStringBuilder().append(s).reverse().toString();int[] next =newint[t.length()];int i =0, j =1;while(j <t.length()){if(t.charAt(i)==t.charAt(j)){ next[j++]=++i;}else{if(i ==0){ j++;}else{ i = next[i -1];}}}int sufix = next[next.length-1];returnnewStringBuilder().append(s.substring(sufix)).reverse().toString()+ s;}}