zoukankan      html  css  js  c++  java
  • 0647. Palindromic Substrings (M)

    Palindromic Substrings (M)

    题目

    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".
    

    Note:

    1. The input string length won't exceed 1000.

    题意

    统计给定字符串中回文子串的个数。

    思路

    当两个回文子串的中心不同时,这两个子串必然是不同的。因此只需要遍历所有的中心位置(单个字符或者是字符之间的空隙),累加不同中心位置对应的回文子串的个数即可得到答案。复杂度为(O(N^2))

    也可使用动态规划进行判断:dp[i][j]表示子串i-j是否为回文串,则有如下递推式:

    [DP[i][j] = (DP[i+1][j-1] && s[i] == s[j]) ]

    也可以使用马拉车算法 - Manacher's Algorithm,复杂度为(O(N))


    代码实现

    Java

    中心判断

    class Solution {
        public int countSubstrings(String s) {
            int count = 0;
            for (int i = 0; i < s.length(); i++) {
                count += countPalindrome(s, i, i) + countPalindrome(s, i, i + 1);
            }
            return count;
        }
    
        // 当p、q相等时,说明是以某个字符为中心扩展
        // 当p、q不等时,说明是以某个空隙为中心扩展
        private int countPalindrome(String s, int p, int q) {
            int count = 0;
            while (p >= 0 && q < s.length() && s.charAt(p--) == s.charAt(q++)) {
                count++;
            }
            return count;
        }
    }
    

    马拉车算法

    class Solution {
        public int countSubstrings(String s) {
            if (s.isEmpty() || s == null) {
                return 0;
            }
    
            int count = 0;
            String t = transform(s);
            int[] radius = new int[t.length()];
            int center = 0;
    
            for (int i = 0; i < t.length(); i++) {
                int rightBound = center + radius[center];
                radius[i] = rightBound >= i ? Math.min(radius[2 * center - i], rightBound - i) : 0;
                while (i + radius[i] + 1 < t.length() && i - radius[i] - 1 >= 0
                        && t.charAt(i + radius[i] + 1) == t.charAt(i - radius[i] - 1)) {
                    radius[i]++;
                }
                center = i + radius[i] > rightBound ? i : center;
                count += (radius[i] + 1) / 2;
            }
            return count;
        }
    
        private String transform(String s) {
            StringBuilder sb = new StringBuilder();
            for (char c : s.toCharArray()) {
                sb.append('#');
                sb.append(c);
            }
            sb.append('#');
            return sb.toString();
        }
    }
    

    JavaScript

    /**
     * @param {string} s
     * @return {number}
     */
    var countSubstrings = function (s) {
      let ans = 0
      const dp = new Array(s.length).fill(0).map(item => [])
    
      for (let len = 1; len <= s.length; len++) {
        for (let start = 0; start + len - 1 < s.length; start++) {
          const end = start + len - 1
    
          if (len === 1) {
            dp[start][end] = true
          } else if (len === 2) {
            dp[start][end] = s[start] === s[end]
          } else {
            dp[start][end] = s[start] === s[end] && dp[start + 1][end - 1]
          }
    
          if (dp[start][end]) ans++
        }
      }
    
      return ans
    }
    
  • 相关阅读:
    积性函数大全(欧拉函数、莫比乌斯反演、杜教筛……)
    Codeforces 1427 G.One Billion Shades of Grey
    Codeforces Global Round 11 A-F题解
    一般难度模板复习
    (补充)证明线性递推相关的Hamilton-Cayley定理
    [ZJOI2018]树
    [ICPC-Beijing 2006]狼抓兔子
    P4869 albus就是要第一个出场
    浅谈算法——线性基
    [COCI2017-2018#1] Deda
  • 原文地址:https://www.cnblogs.com/mapoos/p/14586192.html
Copyright © 2011-2022 走看看