【拒绝算法PUA】3297. 统计重新排列后包含另一个字符串的子字符串数目 I

系列文章目录

【拒绝算法PUA】0x00-位运算
【拒绝算法PUA】0x01- 区间比较技巧
【拒绝算法PUA】0x02- 区间合并技巧
【拒绝算法PUA】LeetCode每日一题系列刷题汇总-2025年持续刷新中

C++刷题技巧总结:
[温习C/C++]0x04 刷题基础编码技巧



LeetCode 3297. 统计重新排列后包含另一个字符串的子字符串数目 I

链接

3297. 统计重新排列后包含另一个字符串的子字符串数目 I

题目

给你两个字符串 word1 和 word2 。

如果一个字符串 x 重新排列后,word2 是重排字符串的 
前缀
 ,那么我们称字符串 x 是 合法的 。

请你返回 word1 中 合法 
子字符串
 的数目。

 

示例 1:

输入:word1 = "bcca", word2 = "abc"

输出:1

解释:

唯一合法的子字符串是 "bcca" ,可以重新排列得到 "abcc""abc" 是它的前缀。

示例 2:

输入:word1 = "abcabc", word2 = "abc"

输出:10

解释:

除了长度为 1 和 2 的所有子字符串都是合法的。

示例 3:

输入:word1 = "abcabc", word2 = "aaabc"

输出:0

 

解释:

1 <= word1.length <= 105
1 <= word2.length <= 104
word1 和 word2 都只包含小写英文字母。

解题方法1

class Solution {
public:
    // 类似于求word1中完全覆盖word2的子串数量
    long long validSubstringCount(string word1, string word2) {
        // 统计word2的所有字母
        int needMatchedCount[26]{};
        for (const char& c : word2) {
            needMatchedCount[c - 'a']++;
        }
        int totalNeed = word2.length();

        // 滑动窗口
        int left = 0;
        long long res = 0;
        for (const char& c : word1) {
            // 遍历右边界
            if (needMatchedCount[c - 'a'] > 0) {
                // 如果当前字符待匹配数量>0,那么待匹配总数-1
                totalNeed--;
            }
            // 遍历到的字符待匹配数量减1,此时不属于word2的字符数量一定<0
            needMatchedCount[c - 'a']--;
            while (totalNeed == 0) {
                // 如果完全匹配,那么缩小左边界
                needMatchedCount[word1[left] - 'a']++;
                if (needMatchedCount[word1[left] - 'a'] > 0) {
                    totalNeed++;
                }
                left++;
            }
            res += left;
        }
        return res;
    }
};

输出:


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值