leetcode647 (return text string: manacher algorithm)

Given a string s, your task is to count how many palindrome substrings are in this string.
Substrings with different start positions or end positions, even if they consist of the same characters, will be regarded as different substrings.

Example:
Input: Input: "bbb"
Output: 6
Explanation: 6 palindrome substrings: "b", "b", "b", "bb", "bb", "bbb"

Problem solution (1): dynamic programming, constructing dynamic programming function F(x, y) to record whether the substring composed of the x-1th character to the y-1th character of the string s is a palindrome string. During dynamic programming, the palindrome string is judged by traversing the string s, starting from finding the palindrome substring of length 1, and increasing the length of the text string successively.

class Solution {
    
    
    public int countSubstrings(String s) {
    
    
           int res=0;
           int len=s.length();
           boolean[][]dp=new boolean[len][len];
           for(int i=0;i<len;i++)
               for(int k=0;k+i<len;k++){
    
    
                   if(i==0) {
    
    
                       dp[k][k + i] = true;
                       res++;
                   }
                   else{
    
    
                       if(s.charAt(k)==s.charAt(k+i)){
    
    
                           if(i==1||dp[k+1][k+i-1]) {
    
    
                               dp[k][k + i] = true;
                               res++;
                           }
                       }
                   }
               }
           return res;
    }
}

Problem solution (2): Traverse the string s, take each character as the center of the palindrome string, expand to both sides, and count the number of palindrome character substrings.

class Solution {
    
    
    public int countSubstrings(String s) {
    
    
         int res=0;
         int left,right;
         for(int i=0;i<s.length();i++) {
    
    
             for (int k = 0; k < 2; k++) {
    
    
                 left=i;
                 right=i+k;
                 while (left >= 0 && right < s.length()) {
    
    
                           if(s.charAt(left)==s.charAt(right)) {
    
    
                               res++;
                               left--;
                               right++;
                           }
                           else 
                               break;
                 }
             }
         }
         return res;
    }
}

Problem solution (three): manacher algorithm

class Solution {
    
    
    public int countSubstrings(String s) {
    
    
        int res=0;
        /*
        * 填充字符串,在两个字符串的中间和两端填充‘#’,使得字符串的长度为奇数
        * 在字符串新的两端填充‘$’、‘!’、防止越界问题
        * 遍历新字符串,以新字符串的每个字符为中心,向外扩展,记录回文字符串的最大半径
        * 设单个字符为中心的回文串最大半径为r,则恢复到原字符串后,还剩下的有效回文字符串个数为r/2
        * 例:d#b#a#b#c,以a为中心,r=4,恢复为原字符串后(dbabc),有效回文字符串个数是(int)4/2=2
        *    #b#b#,以第二个‘#’为中心,r=3,恢复后(bb),有效回文字符串个数是(int)3/2=1
        */
        StringBuffer string=new StringBuffer("$#");
        for(int i=0;i<s.length();i++){
    
    
            string.append(s.charAt(i)+"#");
        }
        string.append("!");
        int len=string.length();
        int[]r=new int[string.length()];
        int center=0;
        int rMax=1;
        /*
        * 我们用int[]r保存s中以每个字符为中心的最大回文字符串半径
        * manacher算法中,我们要维护一个当前的最大回文半径rMax,和这个最大回文半径
        * 所对应的回文中心center,以及最大边界(edge=center+rMax-1),如果当前的字符串中心k在
        * 最大边界内(k<edge),则Math.min(r[2*center-i],edge-i)一定在k的回文字符串半径范围内,
        * 可以设此为向外扩展的初始值,以减少程序运行次数(利用已知回文字符串优化程序运行)
        */
        for(int i=1;i<len-1;i++){
    
    
            if(i>center+rMax-1)
                r[i]=1;
            else{
    
    
                r[i]=Math.min(r[2*center-i],rMax+center-i);
            }
            while(string.charAt(i-r[i])==string.charAt(i+r[i]))
                r[i]++;
            if(r[i]>rMax||i>center+rMax){
    
    
                center=i;
                rMax=r[i];
            }

            res+=r[i]/2;
        }
        return res;

    }
}

Guess you like

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