• 647. Palindromic Substrings


    Given a string, your task is to count how many palindromic substrings in this string.

    The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

    Example 1:

    Input: "abc"
    Output: 3
    Explanation: Three palindromic strings: "a", "b", "c".
    

    Example 2:

    Input: "aaa"
    Output: 6
    Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".


    Step 1: Start a for loop to point at every single character from where we will trace the palindrome string.
    checkPalindrome(s,i,i); //To check the palindrome of odd length palindromic sub-string
    checkPalindrome(s,i,i+1); //To check the palindrome of even length palindromic sub-string

    Step 2: From each character of the string, we will keep checking if the sub-string is a palindrome and increment the palindrome count. To check the palindrome, keep checking the left and right of the character if it is same or not.

    First Loop:
    0_1500788783696_300147d3-e98e-4977-83f1-9eb8213a485e-image.png
    Palindrome: a (Count=1)
    0_1500788808121_fec1dec5-ab5f-44cf-8dbd-eb2780e8d65f-image.png
    Palindrome: aa (Count=2)

    Second Loop:
    0_1500788845582_881440b8-6dde-4b6f-a864-24fef277069b-image.png
    Palindrome: a (Count=3)
    0_1500788872920_61fc20cb-0cb2-4179-8f5a-529cbad7a2ec-image.png
    Palindrome: No Palindrome

    Third Loop:
    0_1500788901120_bf12b13b-ff32-4703-86cf-0bcb54465428-image.png
    Palindrome: b,aba,aabaa (Count=6)
    0_1500788934388_5cc2c31d-404c-456a-a77d-1432bb0c679b-image.png
    Palindrome: No Palindrome

    Forth Loop:
    0_1500788981884_a2d3f30e-0745-4a75-b2c0-940834bd6a84-image.png
    Palindrome: a (Count=7)
    0_1500789009429_f38aa5c2-17ac-47db-8fe9-b9bb4ceb1407-image.png
    Palindrome: aa (Count=8)

    Count = 9 (For the last character)

    Answer = 9

    int count =1;
    public int countSubstrings(String s) {
        if(s.length()==0) 
            return 0;
        for(int i=0; i<s.length()-1; i++){
            checkPalindrome(s,i,i);     //To check the palindrome of odd length palindromic sub-string
            checkPalindrome(s,i,i+1);   //To check the palindrome of even length palindromic sub-string
        }
        return count;
    }    
    
    private void checkPalindrome(String s, int i, int j) {
        while(i>=0 && j<s.length() && s.charAt(i)==s.charAt(j)){    //Check for the palindrome string 
            count++;    //Increment the count if palindromin substring found
            i--;    //To trace string in left direction
            j++;    //To trace string in right direction
        }
    }
    

     

    O(n)的时间复杂度。

    思路:先对字符串进行改造(例如原字符串是"bab",改造后是"#b#a#b#"),接着对改造后的字符串运行Manacher's Algorithm(“马拉车”算法),得到以s[i]为中心的回文串的半径RL[i](不包括中心。例如"a"的半径就是0;"bab"以"a"为中心,半径就是1),显然,以s[i]为中心,RL[i]为半径的回文串中含有的字回文串数目是(RL[i] + 1) / 2个。最后只要将每个(RL[i] + 1) / 2加和就是结果

     

    An O(N) Solution (Manacher’s Algorithm):
    First, we transform the input string, S, to another string T by inserting a special character ‘#’ in between letters. The reason for doing so will be immediately clear to you soon.

    For example: S = “abaaba”, T = “#a#b#a#a#b#a#”.

    To find the longest palindromic substring, we need to expand around each Ti such that Ti-d … Ti+d forms a palindrome. You should immediately see that d is the length of the palindrome itself centered at Ti.

    We store intermediate result in an array P, where P[ i ] equals to the length of the palindrome centers at Ti. The longest palindromic substring would then be the maximum element in P.

    Using the above example, we populate P as below (from left to right):

    T = # a # b # a # a # b # a #
    P = 0 1 0 3 0 1 6 1 0 3 0 1 0

    Looking at P, we immediately see that the longest palindrome is “abaaba”, as indicated by P6 = 6.

    public class Solution {
        public int countSubstrings(String s) {
            String rs = "#";
            //改造
            for(int i = 0; i < s.length(); i++) rs = rs + s.charAt(i) + "#";
            int[] RL = new int[rs.length()];//半径
            int pos = 0, maxRight = 0, count = 0;
            for(int i = 0; i < rs.length(); i++) {
                if(i < maxRight) {
                    RL[i] = Math.min(maxRight - i, RL[2 * pos - i]);
                }
                while(i - RL[i] - 1 >= 0 && i + RL[i] + 1< rs.length() && rs.charAt(i - RL[i] - 1) == rs.charAt(i + RL[i] + 1)) {
                    RL[i]++;
                }
                if(i + RL[i] > maxRight) {
                    pos = i;
                    maxRight = i + RL[i];
                }
                count += (RL[i] + 1) / 2;
            }
            return count;
        }
    }
    

      

      

  • 相关阅读:
    本地存储 localStorage
    正则对象
    面向对象
    事件
    日期对象
    网易适配与淘宝适配
    自动把网页px单位转换成rem
    湖南省web应用软件(中慧杯)
    百度图片审核功能
    百度ai语音识别
  • 原文地址:https://www.cnblogs.com/apanda009/p/7824298.html
Copyright © 2020-2023  润新知