题目:
大根堆思路:
维护最大值,应该首先想到大根堆。C++中对应着priority_queue,这里用pair<int,int>来记录对应的值和在nums中的索引。所以有priority_queue<pair<int,int>> q。在大根堆中,用q.top().first即可获取最大值。对于滑动窗口有三个步骤:处理进入的元素、处理出去的元素、记录结果。直接看代码吧,很清晰的。
大根堆代码
C++代码
class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {//大根堆priority_queue<pair<int,int>> q;//初始化大根堆for(int i=0;i<k;i++){q.emplace(nums[i],i);}//初始化resvector<int> res={q.top().first};//处理后续窗口int len=nums.size();for(int i=k;i<len;i++){//进入q.emplace(nums[i],i);//出去while(q.top().second<=i-k){q.pop();}//记录答案res.push_back(q.top().first);}return res;}
};
对于priority_queue,增添元素为emplace,删除元素为pop。
定义小根堆的话(C++默认大根堆),需要把代码:
priority_queue<pair<int,int>> q;
转换为:(或者直接对元素取负就行)
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
python代码:
class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:q=[]for i in range(k):heapq.heappush(q,(-nums[i],i))res=[-q[0][0]]len_nums=len(nums)for i in range(k,len_nums):heapq.heappush(q,(-nums[i],i))while q[0][1]<=i-k:heapq.heappop(q)res.append(-q[0][0])return res
注意,python中默认的是小根堆 ,需要导入包import heapq
对于加入元素操作:
heapq=[]
heapq.heappush(q,(-nums[i],i))
删除元素操作:
heapq.heappop(q)
双端队列思想:
- 滑动窗口加入元素
每当从末端加入一个元素时,都要跟双端队列的末尾元素进行比较,如果末尾的元素更小,当加入该元素后,末尾元素一定不是最大值,所以在加入该元素之前,将末尾元素pop掉(这里运用while循环)。滑动窗口移出元素
加入该元素后,还要判断双端队列最开始的元素的索引是否在要求的滑动窗口中,如果不在,那需要把最前面的元素pop掉(while循环)。
记录答案
可以考虑到这是一个递减的双端队列,所以最大值永远是第一个元素。
双端队列代码:
C++代码:
class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int len=nums.size();//只记录数组索引的双端队列deque<int> q;//初始化双端队列for(int i=0;i<k;i++){while(!q.empty() && nums[q.back()]<=nums[i]){q.pop_back();}q.push_back(i);}//初始化答案vector<int> res={nums[q.front()]};//滑动窗口---进入/移出/记录答案for(int i=k;i<len;i++){//进入while(!q.empty() && nums[q.back()]<=nums[i]){q.pop_back();}q.push_back(i);//移出while(q.front()<=i-k){q.pop_front();}//记录答案res.push_back(nums[q.front()]);}return res;}
};
python代码:
class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:len_nums=len(nums)q=deque()for i in range(k):while q and nums[q[-1]]<=nums[i]:q.pop()q.append(i)res=[nums[q[0]]]for i in range(k,len_nums):while q and nums[q[-1]]<=nums[i]:q.pop()q.append(i)while q[0]<=i-k:q.popleft()res.append(nums[q[0]])return res
注意需要引入头文件from collections import deque
q=deque()
C++:q.back()
python:q[-1]
#双端队列deque插入/删除元素
q.append(i)
q.pop()
q.popleft()