Leetcode Shortest Palindrome

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值