今天刷随想录,接下来就开始介绍数组操作中另一个重要的方法:滑动窗口。
滑动窗口算法简介
滑动窗口算法是一种通过定义窗口在数据结构上的滑动,以解决问题的方法。通常,窗口由两个指针表示,一个用于维护窗口的起始位置,另一个用于维护窗口的结束位置。算法的核心思想是在遍历过程中,通过移动这两个指针,调整窗口的大小和位置,以满足特定的条件。
算法步骤
-
初始化指针: 设立两个指针,通常表示窗口的起始位置(start)和结束位置(end)。
-
遍历数组: 从数组的第一个元素开始,进行遍历。
-
窗口调整: 在遍历过程中,根据问题的具体条件,通过移动指针调整窗口的大小和位置。
-
更新最优解: 在每一步调整中,更新记录当前问题的最优解。
-
返回结果: 遍历完成后,返回记录的最优解。
案例应用:果树农场水果收集
考虑一个实际问题:在一排果树上收集水果,每个篮子只能装同一类型的水果。我们希望找到一种策略,使得能够收集到的水果数量最大。
具体步骤
-
初始化: 设立两个指针start和end,初始位置都为数组的第一个元素。
-
遍历果树数组: 在遍历的过程中,使用一个字典或数组来记录窗口内每种水果的数量。
-
窗口调整: 如果窗口内水果种类的数量大于2,移动start指针,缩小窗口,直到水果种类数量等于2。
-
更新最大窗口: 在每一步调整中,更新记录的最大窗口大小。
-
返回结果: 遍历完成后,最大窗口的大小即为能够收集到的最大水果数量。
代码实现
#include <iostream>
#include <unordered_map>
#include <vector>using namespace std;int maxFruits(vector<int>& fruits) {int start = 0, end = 0;unordered_map<int, int> fruitCount;int maxWindowSize = 0;while (end < fruits.size()) {// 更新窗口fruitCount[fruits[end]]++;// 窗口调整while (fruitCount.size() > 2) {fruitCount[fruits[start]]--;if (fruitCount[fruits[start]] == 0) {fruitCount.erase(fruits[start]);}start++;}// 更新最大窗口maxWindowSize = max(maxWindowSize, end - start + 1);// 移动窗口end++;}return maxWindowSize;
}int main() {// 示例用法vector<int> fruits = {1, 2, 1, 2, 3};int result = maxFruits(fruits);cout << "最大水果收集量为: " << result << endl;return 0;
}