题目链接
214. 最短回文串
题目描述
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入: "aacecaaa"
输出: "aaacecaaa"
示例 2:
输入: "abcd"
输出: "dcbabcd"
解题思路
1.常规思路
找出字符串s中所有以s[0]为起点的回文字符串中最长的那一个回文字符串,那剩余的元素逆序拼接至开头即可。
2.KMP算法
参考题解
将原字符串翻转,并加在原串后。由于回文串翻转后不变,因此前缀的回文串就等于后缀的回文串(公共前后缀),即求next数组的值。
AC代码
1.常规思路
class Solution {
public String shortestPalindrome(String s) {
char[] cs = s.toCharArray();
if (cs.length <= 1) {
return s;
}
int index = 0;
for (int i = 0; i <= (cs.length - 1) / 2; i++) {
index = Math.max(index, palindrome(cs, i));
}
if (index == cs.length) {
return s;
}
StringBuilder sb = new StringBuilder(s);
return new StringBuilder(s.substring(index + 1, cs.length)).reverse().append(sb).toString();
}
private int palindrome(char[] cs, int i) {
int res = 0;
if (isPalindrome1(cs, i)) {
res = 2 * i;
}
if (isPalindrome2(cs, i)) {
res = 2 * i + 1;
}
return res;
}
// aba情况回文子串
private boolean isPalindrome1(char[] cs, int i) {
for (int j = 0; j < i; j++) {
if (cs[j] != cs[2*i - j]) {
return false;
}
}
return true;
}
// abba情况回文子串
private boolean isPalindrome2(char[] cs, int i) {
if (i >= cs.length / 2) {
return false;
}
for (int j = 0; j <= i; j++) {
if (cs[j] != cs[2*i + 1 - j]) {
return false;
}
}
return true;
}
}
2.KMP算法
class Solution {
int get_next(String needle){
//next的数组大小必须是pattern字符串长度+1,这样才能算出最长公共前后缀的长度
int[] next = new int[needle.length()+1];
next[0] = -1;
next[1] = 0;
int k = 0;
int i = 2;
while(i < next.length){
if(needle.charAt(i-1) == needle.charAt(k)){
k++;
next[i] = k;
i++;
}else if(k == 0){
next[i] = 0;
i++;
}else k = next[k];
}
return next[next.length-1];
}
public String shortestPalindrome(String s) {
if(s.length()<2) return s;
StringBuffer sb = new StringBuffer(s);
StringBuffer temp = new StringBuffer();
//之所以加一个“#”,是因为防止出现s == "aaaa"这种情况,如果没有"#",temp=“aaaaaaaa”,则返回值cnt=8,如果加上“#”,cnt的返回值为s.length()=4;
temp.append(s).append("#").append(sb.reverse().toString());
int cnt = get_next(temp.toString());
if(cnt == s.length()) return s;
else{
String index = s.substring(cnt,s.length());
System.out.println(index);
StringBuffer rever = new StringBuffer(index);
return rever.reverse().append(s).toString();
}
}
}