题目描述
滑动窗口的重点是 确定收缩窗口的判定条件和收缩时的改变过程。
该题目的实质是求出一个最大长度的滑动窗口。用unordered_map<int, int> cnt
哈希表来存储已选中的苹果种类(key)和该种类选中的个数(value)关系,以此为收缩窗口的判定依据。
当cnt
里已存入的键值个数超过两个时,需要收缩窗口。先寻找到左侧边界对应的键值,然后左侧收缩一次时,让键值对应的存入个数减少一个,直至有一个键值对应的存入个数减少为0时,清除该键值,跳出收缩循环,继续向右侧扩展窗口。
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int n = fruits.size();
unordered_map<int, int> cnt; // 定义一个哈希表存已选中的水果种类
int res = 0;
for(int i = 0, j = 0; j < n; j++){
++cnt[fruits[j]]; // fruits[j]的水果下标,对应value加一
while(cnt.size() > 2){ // 当存入刚好超过两个水果时
auto it = cnt.find(fruits[i]); // 寻找左侧边界对应的水果种类
--it->second; // 移除一个水果
if(it->second == 0) // 当对应水果种类全部被被移除后清除该key-value
cnt.erase(it);
i++; // 收缩左边界
}
res = max(res, j - i + 1); // 寻找最大长度
}
return res;
}
};
题目链接:904. 水果成篮