zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    

      

      

  • 相关阅读:
    Android Fragment和FragmentActivity区别和用法
    百度地图
    test
    Activity的跳转与传值
    判断Android应用是否安装、运行
    爬取当当网 Top 500 本五星好评书籍
    TED-WordCloud: 4000+视频标题词云分析
    记第一个爬虫
    requests-html简介
    用requests-html爬取7000+PDF
  • 原文地址:https://www.cnblogs.com/apanda009/p/7824298.html
Copyright © 2011-2022 走看看