

right指针向右探索,并用哈希hash来记录每种水果出现的次数。(进窗口)

unordered_map<int, int> hash; // 开始时完全为空
// 当我们执行:
hash[1]++; // 创建键值对:key=1, value=1
hash[2]++; // 创建键值对:key=2, value=1
hash[3]++; // 创建键值对:key=3, value=1
// 此时哈希表里只有3个元素:
// 键1 → 值1
// 键2 → 值1
// 键3 → 值1
cout << hash.size(); // 输出3,因为确实有3个键值对
size()来判断种类是否大于2,如果大于2就需要进行出窗口操作,先将当前左指针指向的种类个数–,然后判断它是不是为0,为0就使用erase删除(不管是否为0都进行执行后进行下一步,left++,然后继续判断)

right走到数组尽头截止for循环,返回结果。class Solution {
public:
int totalFruit(vector<int>& fruits) {
unordered_map<int,int> hash;//一个int类型的Key对应一个int类型的val
int left = 0, right = 0, ret = 0;
for(right = 0; right < fruits.size(); right++)
{
hash[fruits[right]]++;//进窗口——key(种类)++
while(hash.size() > 2) //判断——水果种类数>2
{
hash[fruits[left]]--;//出窗口,种类--
if(hash[fruits[left]] == 0)//同一类减到0,从水果中删除这个种类
hash.erase(fruits[left]);
left++;
}
ret = max(ret,right-left+1);
}
return ret;
}
};#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
class Solution {
public:
int totalFruit(vector<int>& fruits) {
unordered_map<int, int> hash;//一个int类型的Key对应一个int类型的val
int left = 0, right = 0, ret = 0;
for (right = 0; right < fruits.size(); right++)
{
hash[fruits[right]]++;//进窗口——key(种类)++
while (hash.size() > 2) //判断——水果种类数>2
{
hash[fruits[left]]--;//出窗口,种类--
if (hash[fruits[left]] == 0)//同一类减到0,从水果中删除这个种类
hash.erase(fruits[left]);
left++;
}
ret = max(ret, right - left + 1);
}
return ret;
}
};
int main()
{
vector<int> nums1 = { 1,2,3,2,2 };
int result = Solution().totalFruit(nums1);
cout << result << endl;
return 0;
}


p的每个字符遍历丢进哈希表1里面,记录个数,然后再以p的字符串长度为范围固定滑动窗口的大小然后开始遍历s并丢尽哈希表2里面,来对比他们这个长度范围内的字符种类的个数,相同的话就是异位词返回左指针,然后都++向右遍历找第二个;不相同也是向右找第一个和第二个。

p中相同的字符)的个数。

p中字符个数相比较,到l长度范围内就停止探索(进窗口先停止)。如果小于等于p中的字符个数就count++。
p的len,如果超过就要进行出窗口,先将左指针指向的数据出现的次数与这个字符出现在p中的次数相比较,然后把出窗字符在hash2中的计数减1,如果小于等于就让count--。
count == len,就将最左指针指向的数据尾插到一个容器中,然后寻找下一个所有。class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;//存储索引
int hash1[26] = {0};
int len = p.size();
for(auto ch:p) hash1[ch-'a']++;//统计p中的每个字符的个数
int hash2[26] = {0};//用来统计窗口中每个字符出现的字数
for(int left = 0,right = 0,count = 0;right< s .size();right++ )
{
char in = s[right];//进窗口的字符
if(++hash2[in-'a'] <= hash1[in-'a']) count++;//进窗口,维护count
if(right - left + 1 > len)
{
char out = s[left++];//出窗口的字符
if(hash2[out-'a']-- <= hash1[out-'a']) count--;
}
if(count == len) ret.push_back(left);
}
return ret;
}
};#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;//存储索引
int hash1[26] = { 0 };
int len = p.size();
for (auto ch : p) hash1[ch - 'a']++;//统计p中的每个字符的个数
int hash2[26] = { 0 };//用来统计窗口中每个字符出现的字数
for (int left = 0, right = 0, count = 0; right < s.size(); right++)
{
char in = s[right];//进窗口的字符
if (++hash2[in - 'a'] <= hash1[in - 'a']) count++;//进窗口,维护count
if (right - left + 1 > len)
{
char out = s[left++];//出窗口的字符
if (hash2[out - 'a']-- <= hash1[out - 'a']) count--;
}
if (count == len) ret.push_back(left);
}
return ret;
}
};
int main()
{
string s = "cbaebabacd";
string p = "abc";
vector<int> result = Solution().findAnagrams(s, p);
cout << "[";
for (int i = 0; i < result.size(); i++) {
cout << result[i];
if (i < result.size() - 1) cout << ",";
}
cout << "]" << endl;
return 0;
}
在本篇文章中,我们通过「水果成篮」与「找到字符串中所有字母异位词」两个经典题目,深入理解了 滑动窗口 的核心思想与应用方式。
🚀 敬请期待下一篇: 【C++】优选算法必修篇之实战:串联所有单词的子串 & 最小覆盖子串