【Hot100】239. 滑动窗口最大值
目录
- 引言
- 滑动窗口最大值
- 暴力求解解题
- 采用优先级队列优化
- 🙋♂️ 作者:海码007
- 📜 专栏:算法专栏
- 💥 标题:【Hot100】239. 滑动窗口最大值
- ❣️ 寄语:书到用时方恨少,事非经过不知难!
引言
滑动窗口最大值
- 🎈 题目链接:
- 🎈 做题状态:一开始想到一个暴力求解
暴力求解解题
暴力求解,这种时间复杂度有点高。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if (nums.size() < k) return {};
// 暴力计算,时间复杂度O(n*k)
vector<int> result;
for (int i = 0; i <= nums.size() - k; ++i)
{
int maxV = nums[i];
for (int j = i; j < i + k; ++j)
{
maxV = max(maxV, nums[j]);
}
result.push_back(maxV);
}
return result;
}
};
采用优先级队列优化
在最开始想着要维护一个最大值,想到了使用优先级队列适配器来实现,但是优先级队列只能移除队列顶部元素,不能给定一个值让其移除。所以当滑动窗口右移时,需要将左边界的值给移除掉。
所以如何直到队列中维护的数据是否处于滑动窗口中就很关键。这里使用优先级队列存储 pair<int, int> {value: index} 根据index来判断是否处于滑动窗口的左边界的左侧。这是一个很巧妙的地方。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if (nums.size() < k) return {};
vector<int> result;
priority_queue<pair<int, int>> pq;
// 首先插入k个元素
for (int i = 0; i < k; ++i)
{
pq.push({nums[i], i});
}
result.push_back(pq.top().first);
// 遍历剩余的元素
for (int i = k; i < nums.size(); ++i)
{
// 首先将当前滑动窗口右边界的元素插入到优先级队列中
pq.push({nums[i], i});
// 然后再判断当前优先级队列中的最大值是否是位于左边界的左侧,如果是则循环移除。
// 因为可能需要移除多次,如果之前左侧数值小于最大值是不会被移除的,所以这里得循环移除
while(pq.top().second < i - k + 1)
{
// index < i - k + 1 时说明当前index处于左边界左侧
pq.pop();
}
// 再将最大值添加到结果中
result.push_back(pq.top().first);
}
return result;
}
};