leetcode214. Shortest Palindrome构造最短回文串

问题:给定一个字符串str,只允许在首部添加字符,求构造的最短回文串的长度。

思路:找到以str[n-1]为结尾的最长回文串,设为str[i,n-1];再用前半部分的翻转链接到该串即可:reserve(str[0,i-1])+str

实现:若str[i,n-1]是以str[n-1]为结尾的最长回文串,则反转str后,有reserve(str)[0,n-i-1] equals str[i,n-1],于是转化为reserve(str)+str的最长公共前后缀问题。为避免前后缀越界,用两个不同的特殊字符标记。

class Solution {
    public String shortestPalindrome(String s) {
        if(s.length()==0){
        	return s;
        }
        StringBuilder sb=new StringBuilder(s);
        sb.append('#');//加一个标识防止s+reverse(s)得到的最长公共前后缀长度超过原串
        sb.append(new StringBuilder(s).reverse().toString());
        sb.append('!');//在最后任意加一个字符(遵循kmp的next数组的语义,求目标最长公共前后缀),不与标志字符‘#’相同即可。
        return new StringBuilder(s.substring(getNext(sb.toString())[sb.length()-1])).reverse().append(s).toString();
    }
    /**
     * kmp算法.通过模式串得失配next数组--‘next[i],在i位置发生失配’,pattern[0,i-1]的最长公共前后缀'长度',又下一个字符的索引值==长度
     * next[i],pattern[0,i-1]的最长公共前后缀的长度。notice:length((前缀|后缀))<=length(str)-1,即前缀后缀的概念不含字符串本身
     */
    private int[] getNext(String pattern){
    	int[] next=new int[pattern.length()];
    	next[0]=-1;
    	int pre;//待验证字符索引,关键变量
    	for(int i=1;i
变种:若只能从尾部加字符,则转化为求str+reserve(str)的最长公共前后缀


你可能感兴趣的:(leetcode)