Count Beautiful Substrings II

Count Beautiful Substrings II

You are given a string s and a positive integer k.

Let vowels and consonants be the number of vowels and consonants in a string.

A string is beautiful if:

  • vowels == consonants.
  • (vowels * consonants) % k == 0, in other terms the multiplication of vowels and consonants is divisible by k.

Return the number of non-empty beautiful substrings in the given string s.

substring is a contiguous sequence of characters in a string.

Vowel letters in English are 'a''e''i''o', and 'u'.

Consonant letters in English are every letter except vowels.

 

Example 1:

Input: s = "baeyh", k = 2
Output: 2
Explanation: There are 2 beautiful substrings in the given string.
- Substring "baeyh", vowels = 2 (["a",e"]), consonants = 2 (["y","h"]).
You can see that string "aeyh" is beautiful as vowels == consonants and vowels * consonants % k == 0.
- Substring "baeyh", vowels = 2 (["a",e"]), consonants = 2 (["b","y"]).
You can see that string "baey" is beautiful as vowels == consonants and vowels * consonants % k == 0.
It can be shown that there are only 2 beautiful substrings in the given string.

Example 2:

Input: s = "abba", k = 1
Output: 3
Explanation: There are 3 beautiful substrings in the given string.
- Substring "abba", vowels = 1 (["a"]), consonants = 1 (["b"]).
- Substring "abba", vowels = 1 (["a"]), consonants = 1 (["b"]).
- Substring "abba", vowels = 2 (["a","a"]), consonants = 2 (["b","b"]).
It can be shown that there are only 3 beautiful substrings in the given string.

Example 3:

Input: s = "bcdf", k = 1
Output: 0
Explanation: There are no beautiful substrings in the given string.

 

Constraints:

  • 1 <= s.length <= 5 * 104
  • 1 <= k <= 1000
  • s consists of only English lowercase letters.

 

解题思路

  这题难的地方是在数论的部分,把 x20(modk),找到一个 m 等价变成 x0(modm) 还是很难想到的。

  还是很容易知道是哈希表维护统计那一类题目。先将字符串构造出一个序列 a,如果 stri 是元音字母,则 ai=1,否则 stri 是辅音字母,则 ai=1。然后对序列 a 求前缀和得到 s,当枚举到右端点 r,那么子数组的左端点 l[0,r1] 就要满足 srsl=0,即在左边找到满足 sl=srl 的数量。

  还要满足另外一个条件,(rl2)20(modk),式子等价于 (rl2)2=xk,xZ。继续推有

(rl2)2=xk(rl)2=4xk(rl)20(mod4k)

  然后想到说能不能把左式的平方去掉,即找到一个 m,使得 rl0(modm) 与上式的同余方程是等价的。对 4k 进行质因数分解得到 4k=p1α1p2α2pnαn,那么很明显对于每一项 piαirl 的质因数分解也必须含有 piβi2βiαi,即 βiαi2。因此有 m=p1α12p2α22pnαn2,那么两个同余方程就可以等价了。

  因此把哈希表开成两维,当枚举完右端点 r,维护 mp[sr][rmodm]mp[sr][rmodm]+1 即可。由于 sr 可能是负数所以需要加上一个偏移量 n

  AC 代码如下,时间复杂度为 O(k+n)

class Solution {
public:
    long long beautifulSubstrings(string str, int k) {
        int n = str.size();
        vector<int> s(n + 1);
        set<char> st({'a', 'e', 'i', 'o', 'u'});
        for (int i = 1; i <= n; i++) {
            s[i] = s[i - 1];
            if (st.count(str[i - 1])) s[i]++;
            else s[i]--;
        }
        int m = 1;
        k <<= 2;
        for (int i = 2; i * i <= k; i++) {
            if (k % i == 0) {
                int s = 0;
                while (k % i == 0) {
                    s++;
                    k /= i;
                }
                s = s + 1 >> 1;
                while (s--) {
                    m *= i;
                }
            }
        }
        if (k > 1) m *= k;
        vector<vector<int>> mp(n * 2 + 1, vector<int>(m));
        long long ret = 0;
        for (int i = 1; i <= n; i++) {
            mp[s[i - 1] + n][(i - 1) % m]++;
            ret += mp[s[i] + n][i % m];
        }
        
        return ret;
    }
};

 

参考资料

  子数组统计的套路【力扣周赛 373】:https://www.bilibili.com/video/BV19N411j7Dj/

  赛事活动丨[第373 场周赛]式酱的解题报告:https://leetcode.cn/circle/discuss/k0kT9w/

posted @   onlyblues  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-11-28 D. Range = √Sum
Web Analytics
点击右上角即可分享
微信分享提示