leetcode214 (shortest palindrome: manacher algorithm)

Given a string s, you can convert it to a palindrome by adding characters in front of the string. Find and return the shortest palindrome that can be converted in this way.

Example 1:
Input: "aacecaaa"
Output: "aaacecaaa"

Solution: Find out the prefix palindrome string of the string, and then reverse the remaining string and add it to the front end of the string. The manacher algorithm can be used to find the prefix palindrome string of the string.

class Solution {
    
    
    public String shortestPalindrome(String s) {
    
    
        int palindrome=0;
        StringBuffer S=new StringBuffer();
         /*
        * 填充字符串,在两个字符串的中间和两端填充‘#’,使得字符串的长度为奇数
        * 在字符串新的两端填充‘$’、‘!’、防止越界问题
        * 遍历新字符串,以新字符串的每个字符为中心,向外扩展,记录回文字符串的最大半径
        * 回文字符串的长度:回文字符串半径-1
        */
        for(int i=0;i<s.length();i++){
    
    
            if(i==0)
                S.append("!");
            S.append("#"+s.charAt(i));
        }
        S.append("#$");
         /*
        * 我们用int[]r保存s中以每个字符为中心的最大回文字符串半径
        * manacher算法中,我们要维护一个当前的最大回文半径rMax,和这个最大回文半径
        * 所对应的回文中心center,以及最大边界(right=center+rMax-1),如果当前的字符串中心k在
        * 最大边界内(k<edge),则Math.min(r[2*center-i],right-i)一定在k的回文字符串半径范围内,
        * 可以设此为向外扩展的初始值,以减少程序运行次数(利用已知回文字符串优化程序运行)
        */
        int rMax=1;
        int center=0;
        int right=0;
        int[]r=new int[S.length()];
        for(int i=1;i<S.length()-1;i++){
    
    
            if(i<=right)
                r[i]=Math.min(r[2*center-i],right-i+1);
            else
                r[i]=1;
            while(S.charAt(i-r[i])==S.charAt(i+r[i])){
    
    
                r[i]++;
            }
            if(r[i]>rMax||i>right){
    
    
                center=i;
                rMax=r[i];
                right=rMax+center-1;
            }
            //如果r[i]==i,则说明是前缀回文字符串
            if(r[i]==i)
                palindrome=r[i]-1;
        }
        String add=palindrome==s.length()?"":s.substring(palindrome);
        return new String(new StringBuffer(add).reverse().toString()+s);
    }
}

Guess you like

Origin blog.csdn.net/CY2333333/article/details/108312614