Shortest Palindrome

update Sep 5 2018, 23:11

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:

  class Solution {
      public String shortestPalindrome(String s) {
          String t = s + "#" + new StringBuilder().append(s).reverse().toString();
          int[] next = new int[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];
          return new StringBuilder().append(s.substring(sufix)).reverse().toString() + s;
      }
  }

results matching ""

    No results matching ""