214. Shortest Palindrome
by Botao Xiao
214. Shortest Palindrome
Question
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"
Thinking:
- Method:
- 找到从0开始的最长对称,将剩余的字符在开头补全。
class Solution {
public String shortestPalindrome(String s) {
if(s == null || s.length() == 0) return s;
int len = s.length();
int max = 0;
for(int i = 1; i <= len; i++){
if(check(s.substring(0, i)))
max = Math.max(max, i);
}
StringBuilder sb = new StringBuilder();
for(int i = len - 1; i >= max; i--){
sb.append(s.charAt(i));
}
sb.append(s);
return sb.toString();
}
private boolean check(String s){
char[] arr = s.toCharArray();
int len = s.length();
for(int i = 0; i < len / 2; i++)
if(arr[i] != arr[len - 1 - i]) return false;
return true;
}
}
- Method 2: KMP
- 找出s#s.reverse的最长相同前后缀。
- KMP的next数组。
class Solution {
public String shortestPalindrome(String s) {
if(s == null || s.length() == 0) return s;
String ss = s + "#" + new StringBuilder(s).reverse().toString();
int[] next = new int[ss.length()];
next[0] = -1;
for(int i = 1, j = -1; i < ss.length(); i++){
while(j > -1 && ss.charAt(i) != ss.charAt(j + 1))
j = next[j];
if(ss.charAt(i) == ss.charAt(j + 1)) j++;
next[i] = j;
}
return new StringBuilder(s.substring(next[ss.length() - 1] + 1, s.length())).reverse().toString() + s;
}
}
二刷
- We can analyze one of the questions: aacecaaa
- We first assume we have a result, a + aacecaaa, so we want to find the “a”.
- We create a new String aacecaaa # aaacecaa, where the third part is the reverse of the string and the first part is the original string. So the created string is palindrone.
- We want to find the longest common prefix and suffix. Where we find the a is the remain part of s, if not only a, we need to reverse the remain string.
class Solution { public String shortestPalindrome(String s) { String ss = s + "#" + new StringBuilder(s).reverse().toString(); int len = ss.length(); int[] next = new int[len]; next[0] = -1; for(int i = 1, j = -1; i < len; i++){ while(j > -1 && ss.charAt(i) != ss.charAt(j + 1)){ j = next[j]; } if(ss.charAt(j + 1) == ss.charAt(i)) j++; next[i] = j; } return new StringBuilder(ss.substring(next[len - 1] + 1, s.length())).reverse().toString() + s; } }
Reference:
Subscribe via RSS