Leetcode Shortest Palindrome,本算法主要在于如何加速匹配过程。如果使用常规的判断串s的最长前缀回文串,是不适合的,这样的算法复杂度达到了0(n^2)。如果我们从后,以及从前进行回文串匹配,可以加速,算法的相关步骤如下:
1. 按照kmp算法求于串s的kmpnext数组。
2. 当前匹配串位置为begin,从后向前的串匹配位置为end,以及后部截取位置为cur。
3. 如果begin = 0,快速移动end直到s[end] = s[begin].
4. 如果s[begin] = s[end],则begin向后推进,end向后推进。
5. 如果s[begin] != s[end], 则begin回到kmpnext[begin],并且根据begin减少的长度,计算cur的值。
6. 对begin进行增加,对end进行减小。
7. 如果begin < end,回到第3步。
8. reverse(s[cur…s.length() - 1]) + s做为结果值。
相java代码如下:
import java.util.*;
/**
* This problem should combine the kmp algorithm to minimize the repeat.
* First we calculate the kmp array, and then we use it the process the
* origin String to get the result
*/
public class Solution {
public String shortestPalindrome(String s) {
if (s.length() == 0) {
return s;
}
int end = s.length() - 1;
int begin = 0;
int cur = s.length();
int tmp;
String re = "";
// the array is used to recording the kmp backtrack index
int[] kmpnext = new int[s.length()];
int beginPre = kmpnext[0] = -1;
// preprocess the kmp array backtrack
while (begin < s.length() - 1) {
while (beginPre > -1 && s.charAt(begin) != s.charAt(beginPre)) {
beginPre = kmpnext[beginPre];
}
beginPre++;
begin++;
if (s.charAt(begin) == s.charAt(beginPre)) {
kmpnext[begin] = kmpnext[beginPre];
} else {
kmpnext[begin] = beginPre;
}
}
begin = 0;
// scan the array, using the kmp algorithm to acccelerate the
// scan speed
while (begin < end && cur > 0) {
// find the first s[end] which equals to s[0]
if (begin <= 0 && s.charAt(0) != s.charAt(end)) {
begin = 0;
while (begin < end && s.charAt(0) != s.charAt(end)) {
end--;
}
cur = end + 1;
}
// process the no equal
if (begin < end && s.charAt(begin) != s.charAt(end)) {
tmp = begin - kmpnext[begin];
tmp = cur - tmp > 0? cur - tmp : 0;
cur = tmp;
begin = kmpnext[begin];
} else {
// process the equals
begin++;
end--;
}
}
return new StringBuilder(s.substring(cur)).reverse().toString() + s;
}
public static void main(String[] args) {
Solution so = new Solution();
System.out.println("Result: " + so.shortestPalindrome(args[0]));
}
}
测试: java Solution abcdef
Result: fedcbabcdef