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;
        }
    }
    

      

      

  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/apanda009/p/7824298.html
Copyright © 2011-2022 走看看