题意:给定一个数组和一个窗口大小k,从左往右滑动窗口,依次求出窗口中的最大值。
思路:
1. 最开始想到的是采用单调队列,队列维护从大到小的值的下标,这样就可以判断队首的下标是否在滑动窗口的范围之外,如果在范围之外,那么弹出队列的下标。如果当前位置大于等于k-1时,开始加入最大值。
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.push_back(i);
}else{
//维护单调队列
while(!q.empty() && nums[i] > nums[q.back()]){
q.pop_back();
}
q.push_back(i);
}
//在窗口之外,弹出
while(i - q.front()+1 > k) q.pop_front();
if(i >= k-1) res.push_back(nums[q.front()]);
}
return res;
}
思路2:后来看答案的时候发现还可以用优先队列,队列存储的是<值,下标>,每次判断堆顶的下标是否在窗口之内。
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
priority_queue<pair<int,int>> q;
int n = nums.size();
vector<int> res;
for(int i = 0; i < k; i++){
q.push({nums[i], i});
}
res.push_back(q.top().first);
for(int i = k; i < n; i++){
q.push({nums[i], i});
//判断是否 在窗口之内
while(q.top().second <= i - k){
q.pop();
}
res.push_back(q.top().first);
}
return res;
}