题意:给出一个字符串,通过在字符串前添加字符,使得新的字符串为最短的对称字符串
思路:假设原字符串为s,将其取反的字符串为text,求text的后缀与s的前缀相同时的索引,将text与s索引后的字符拼接起来就是要求的结果
具体代码如下:
public class Solution
{
private int[] kmp_table(String s)
{
int[] next = new int[s.length()];
next[0] = -1;
int j = 0;
for (int i = 1; i < s.length(); i++) {
int k = next[i - 1];
while (k > -1 && s.charAt(k) != s.charAt(i - 1)) {
k = next[k];
}
next[i] = k + 1;
}
return next;
}
private int kmp_search(String text, String pattern)
{
int[] next = kmp_table(pattern);
int m = 0, i = 0;
while (m + i < text.length()) {
while (pattern.charAt(i) == text.charAt(m + i)) {
if (m + i == text.length() - 1) {
return m;
}
i++;
}
m += i - next[i];
i = next[i] > -1 ? next[i] : 0;
}
return 0;
}
public String shortestPalindrome(String s)
{
if (s.isEmpty()) return s;
String text = new StringBuilder(s).reverse().toString();
int index = kmp_search(text, s);
StringBuilder ans = new StringBuilder();
ans.append(text);
ans.append(s.substring(text.length() - index));
return ans.toString();
}
}
解法二:
public class Solution {
private int[] kmp_table(String s)
{
int[] next = new int[s.length()];
next[0] = -1;
int j = -1, i = 0;
while (i < s.length())
{
while (j > -1 && s.charAt(i) != s.charAt(j))
{
j = next[j];
}
i++;
j++;
if (i < s.length() && j < s.length())
{
if (s.charAt(i) == s.charAt(j)) next[i] = next[j];
else
{
next[i] = j;
}
}
}
return next;
}
private int kmp_search(String text, String pattern)
{
int[] next = kmp_table(pattern);
int m = 0, i = 0;
while (m < text.length()) {
while (i > -1 && pattern.charAt(i) != text.charAt(m)) {
i = next[i];
}
m++;
i++;
if (i >= pattern.length())
{
break;
}
}
return m - i;
}
public String shortestPalindrome(String s)
{
if (s.isEmpty()) return s;
String text = new StringBuilder(s).reverse().toString();
int index = kmp_search(text, s);
StringBuilder ans = new StringBuilder();
ans.append(text);
ans.append(s.substring(text.length() - index));
return ans.toString();
}
}