C++ 滑动窗口详解:进阶题解与思维分析
前言
在算法的世界中,滑动窗口是一种极具优雅和灵活性的算法技巧。通过更加灵活的策略、动态调整窗口,我们将解决一系列复杂的算法挑战,进一步揭示滑动窗口的无限可能。
第二章:进阶挑战
2.1 水果成篮
题目链接:904. 水果成篮
题目描述:
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果种类。你想要尽可能多地收集水果,但是有一些规则:
- 你有两个篮子,每个篮子只能装一种类型的水果,篮子的容量无限制。
- 你可以选择任意一棵树开始采摘,但必须从这棵树开始依次向右采摘每棵树上的水果。
- 一旦遇到某棵树上的水果不符合篮子中的水果种类,你必须停止采摘。
返回你能采摘的最多的水果数量。
示例 1:
- 输入:
fruits = [1,2,1] - 输出:
3 - 解释:你可以采摘所有 3 棵树上的水果。
示例 2:
- 输入:
fruits = [0,1,2,2] - 输出:
3 - 解释:你只能采摘
[1,2,2]这三棵树的水果。如果从第 1 棵树开始采摘,只能采摘到[0,1]。
提示:
1 <= fruits.length <= 10^50 <= fruits[i] < fruits.length
解法一:滑动窗口
算法思路: 本题是典型的滑动窗口问题。要求我们找到一个连续区间,其中只能有两种不同种类的水果(即至多两个不同元素)。通过滑动窗口,我们可以动态调整区间大小,保持窗口内水果种类不超过两种。
具体步骤:
- 用一个哈希表
hash记录滑动窗口内的水果种类和数量。 - 滑动窗口的右边界
right向右移动,每次将新水果加入哈希表。 - 如果哈希表中记录的水果种类超过两个,左边界
left开始向右移动,直到窗口内水果种类不超过两个为止。 - 在每次满足条件时,更新最大收集到的水果数量
ret。
代码实现:
#include <unordered_map>
#include <vector>
using namespace std;
class Solution {
public:
{
unordered_map<, > hash;
ret = ;
left = ;
( right = ; right < fruits.(); ++right) {
hash[fruits[right]]++;
(hash.() > ) {
hash[fruits[left]]--;
(hash[fruits[left]] == ) {
hash.(fruits[left]);
}
left++;
}
ret = (ret, right - left + );
}
ret;
}
};


