一、定义
滑动窗口算法(Sliding Window Algorithm)是一种用于解决数组或字符串中子数组或子串问题的优化技术。它通过维护一个窗口(通常是数组或字符串的一个连续子区间),在遍历过程中动态调整窗口的起始和结束位置,从而高效地解决问题。
滑动窗口的核心思想是:
窗口大小固定:窗口的大小在滑动过程中保持不变。
窗口大小可变:窗口的大小根据条件动态调整。
二、使用场景
滑动窗口算法通常用于以下场景:
1.子数组/子串问题:
2.固定窗口大小问题:
3.优化暴力解法:
三、示例
1.例题1:固定窗口大小
【题目描述】给定一个数组和一个整数 k
,计算所有大小为 k
的子数组的平均值。
【题目分析】
(1) 什么是子数组?
子数组是数组中连续的一段元素。
例如,数组 [1, 3, 2, 6, -1]
的子数组包括 [1, 3, 2]
、[3, 2, 6]
等。
(2)什么是大小为 k
的子数组?
(3)什么是子数组的平均值?
子数组的平均值是指子数组中所有元素的和除以子数组的长度。
例如,子数组 [1, 3, 2]
的平均值是 (1 + 3 + 2) / 3 = 2
。
(4)问题的目标
【解题思路】
(1)暴力解法
(2)滑动窗口优化
#include <iostream> using namespace std; void sw(int nums[], int n, int k) { if (n < k) return; // 如果数组长度小于k,直接返回 double windowSum = 0; // 初始化窗口 for (int i = 0; i < k; i++) { windowSum += nums[i]; } cout << windowSum / k << " "; // 滑动窗口 for (int i = k; i < n; i++) { windowSum += nums[i] - nums[i - k]; // 加上新元素,减去旧元素 cout << windowSum / k << " "; } cout << endl; } int main() { int nums[] = {1, 3, 2, 6, -1, 4, 1, 8, 2}; int n = sizeof(nums) / sizeof(nums[0]); int k = 5; sw(nums, n, k); return 0; }
【过程解释】
初始化窗口:
滑动窗口:
图示:
第一次:(1+3+2)/3
第二次:(3+2+6)/3 ,对比上一次,少了第一个数1,多了后一个数6
第二次:(2+6-1)/3 ,对比上一次,少了上一个数2,多了后一个数-1