11 滑动窗口最大值

给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的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 731 [3 -1 -3] 5 3 6 731 3 [-1 -3 5] 3 6 751 3 -1 [-3 5 3] 6 751 3 -1 -3 [5 3 6] 761 3 -1 -3 5 [3 6 7]7

示例 2:

输入:nums = [1], k = 1输出:[1]

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104
  • 1 <= k <= nums.length

思路

1、创建一个大小为k的大顶堆,用pair<int,int>构建元素,第一个是数组的值,第二个是数组的下标。创建两个指针,left=0、right=k-1,把指针中间的数字先加入大顶堆,创建临时的vector用于存放最大值。

2、从堆顶拿一个元素,判断这个元素的下标是否是在left和right之间的,是则将元素放入答案中,否则将这个堆顶元素删除,继续获取堆顶元素,循环判断。

3、循环结束条件right要大于数组的下标时,结束循环。

class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> _ans; int n=nums.size(); if(n<k) return _ans; priority_queue<pair<int,int> > max_head; for(int i=0;i<k;i++){ max_head.push({nums[i],i}); } int left=0,right=k-1; while(1){ pair<int,int> emit=max_head.top(); while(emit.second<left){ max_head.pop(); emit=max_head.top(); } _ans.push_back(emit.first); left++; right++; if(right>=n) break; max_head.push({nums[right],right}); } return _ans; } };
//priority_queue(优先队列) #include <queue> // priority_queue 在 <queue> 头文件中 //创建大顶堆 std::priority_queue<pair<int,int>> pri_queue; std::priority_queue< int, // 元素类型 std::vector<int>, // 底层容器(必须是 vector 或 deque) std::greater<int> // 比较器:小顶堆 > min_heap; pair<int,int> emit; //访问pair的第一个元素:emit.first //访问pair的第二个元素:emit.second

基本函数

操作函数O(log n)说明
插入元素push(value)O(log n)插入元素到队列
删除堆顶pop()O(log n)移除优先级最高的元素
访问堆顶top()O(1)返回优先级最高的元素(不删除)
判空empty()O(1)队列是否为空
大小size()O(1)元素个数

底层容器选vectordeque有什么区别?

priority_queue支持vectordeque作为底层容器(也支持其他满足条件的序列容器,如list不支持随机访问,所以不行)。两者的区别主要体现在内存布局性能特征上:

对比维度std::vector<int>std::deque<int>
内存布局连续内存,所有元素存储在一块连续的空间中分段内存,由多个固定大小的内存块组成
缓存友好性✅ 极高,遍历/堆操作时 CPU 缓存命中率高❌ 较差,元素分散在不同内存块,缓存命中率低
内存扩容容量不足时会重新分配并拷贝/移动所有元素,可能导致迭代器失效新增块时不会移动已有元素,迭代器不会失效
内存开销较小,仅有一个动态数组的开销较大,需要额外维护指向各个块的指针数组
尾部插入性能均摊 O(1),但扩容时有峰值开销均摊 O(1),无峰值开销
适用场景优先推荐,性能更好当需要避免扩容时移动开销巨大的元素类型时可选

推荐一个零声教育学习教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习:链接