214-shortest-palindrome
Question
https://leetcode.com/problems/shortest-palindrome/description/
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:
Given "aacecaaa", return "aaacecaaa".
Given "abcd", return "dcbabcd".
Thought Process
- Expand and Reach the End
- The goal is to find the longest palindrome starting from first character
- So we try to expand each character as palindromic center
- After finding the length, then the answer is simply n - len + n
- Time complexity O(n^2)
- Space complexity O(1)
- KMP
- KMP explains here, https://blog.csdn.net/v_july_v/article/details/7041827
- Building Partial Table, http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/
- Using KMP table can help us determine the longest palindrome from first character
- The trick is use s + "#" + reverse(s), and the last cell of the table will be the length
- The match of proper prefix of s and proper suffix of reverse s indicates the that has to be a palindrome
- Time complexity O(n)
- Space complexity O(n)
- Manacger
- asdasd
Solution
class Solution {
public String shortestPalindrome(String s) {
if (s.length() <= 1) return s;
char[] chars = s.toCharArray();
int n = s.length(), len = 1;
for (int i = 1; i <= n / 2; i++) {
len = Math.max(len, expand(chars, i - 1, i));
len = Math.max(len, expand(chars, i, i));
}
StringBuilder sb = new StringBuilder();
for (int i = n - 1; i >= len; i--) sb.append(chars[i]);
sb.append(s);
return sb.toString();
}
private int expand(char[] chars, int i, int j) {
while (i >= 0 && j < chars.length && chars[i] == chars[j]) {
i--;
j++;
}
return i == -1 ? j - i - 1 : 0;
}
}
class Solution {
public String shortestPalindrome(String s) {
String rev = reverse(s);
int n = s.length();
int len = kmp(s + "#" + rev);
return rev.substring(0, n - len) + s;
}
private String reverse(String s) {
StringBuilder sb = new StringBuilder(s);
return sb.reverse().toString();
}
private int kmp(String s) {
int n = s.length(), i = 0;
int[] table = new int[n];
char[] chars = s.toCharArray();
for (int j = 1; j < n; j++) {
while (i > 0 && chars[i] != chars[j]) i = table[i - 1];
if (chars[i] == chars[j]) i++;
table[j] = i;
}
return table[n - 1];
}
}