Leetcode Shortest Palindrome

来源:互联网 发布:算法 第四版 微盘 编辑:程序博客网 时间:2024/05/22 02:20

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 abcdefResult: fedcbabcdef
1 0
原创粉丝点击