给定一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。滑动窗口每次只向右移动一位。要求返回滑动窗口中的最大值。
示例 1
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2
输入:nums = [1], k = 1
输出:[1]
实时计算网络流量的滑动窗口最大值,帮助及时发现流量高峰,预防网络拥塞。
假设我们有一个网络流量监控系统,它每秒记录一次网络流量数据(以 Mbps
为单位)。我们希望实时监控网络流量,以便及时发现流量高峰,预防网络拥塞。我们可以使用滑动窗口算法来计算过去 10
秒内的最大流量。
在实时数据流中,计算滑动窗口内的最大值,快速获取数据峰值,助力实时决策。
假设我们有一个实时数据流,每秒记录一次传感器数据。我们希望实时计算过去 5
秒内的数据最大值,以便快速获取数据峰值,助力实时决策。
对图像数据应用滑动窗口技术,计算局部最大值,用于特征提取和边缘检测。
存储窗口内元素的最大值是目标,但关键在于如何高效地获取这个最大值。
O(n)
。#include
#include
#include
using namespace std;
vector<int> maxSlidingWindow(vector<int> &nums, int k)
{
deque<int> q;
vector<int> res;
for (int i = 0; i < nums.size(); i++)
{
// 移除不在窗口范围内的元素
if (!q.empty() && q.front() == i - k)
{
q.pop_front();
}
// 移除所有比新元素小的元素
while (!q.empty() && nums[q.back()] < nums[i])
{
q.pop_back();
}
// 将新元素加入队列
q.push_back(i);
// 将窗口内的最大值加入结果
if (i >= k - 1)
{
res.push_back(nums[q.front()]);
}
}
return res;
}
int main()
{
vector<int> nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
vector<int> res = maxSlidingWindow(nums, k);
for (auto i : res)
{
cout << i << " ";
}
cout << endl;
return 0;
}
O(logn)
。在最坏情况下,数组 nums
中的元素单调递增,那么最终优先队列中包含了所有元素,没有元素被移除。总时间复杂度为 O(nlog n)
。#include
#include
#include
using namespace std;
vector<int> maxSlidingWindow(vector<int> &nums, int k)
{
priority_queue<pair<int,int>> q;
vector<int> res;
for (int i = 0; i < nums.size(); i++)
{
// 将元素和其下标加入优先队列
q.emplace(nums[i], i);
// 删除不在滑动窗口中的元素
while (!q.empty() && q.top().second <= i - k)
{
q.pop();
}
// 滑动窗口长度达到k时,保存最大值
if (i >= k - 1)
{
res.push_back(q.top().first);
}
}
return res;
}
int main()
{
vector<int> nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
vector<int> res = maxSlidingWindow(nums, k);
for (auto i : res)
{
cout << i << " ";
}
cout << endl;
return 0;
}
https://github.com/0voice