系列文章目录
【拒绝算法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;
}
};
输出: