Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see thek numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7]
, and k = 3.
Window position Max --------------- ----- [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
Therefore, return the max sliding window as [3,3,5,5,6,7]
.
解答:
定义一个双端队列q,里面存放窗口中的局部值,位置从大到小;
当输入一个数据时,从队尾查看,若该数据小于队尾值,则加入队列中;(防止当前面大的值退出后,找不到第二大的值)
若该数据大于队尾值,则把队尾值依次pop出来,直到遇到队尾的值比当前值大或者队列为空,再把当前值加入进去;
每次取当前窗口的最大值时,就去q的头结点就行;
同时,注意这里是将数据的位置放入q中,目的是为了记录,如果窗口移动下一位,最前面的值是q中的最大值时,此时需要将q的头结点的值退出来,判断的时候就需要判断是否q.front() == j - k, 如果满足,则由于窗口移动,这个最大值已经不在窗口中的,因此需要pop q.front()
代码如下:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int>dq;
vector<int>res;
if(nums.size() == 0 || k == 0) return res;
for(int i = 0; i < k; i++){
if(i == nums.size()) break;
while(!dq.empty() && nums[dq.back()] < nums[i])
dq.pop_back();
dq.push_back(i);
}
res.push_back(nums[dq.front()]);
for(int j = k; j < nums.size(); j++){
while(!dq.empty() && nums[dq.back()] < nums[j])
dq.pop_back();
dq.push_back(j);
if(dq.front() == j - k)
dq.pop_front();
res.push_back(nums[dq.front()]);
}
return res;
}
};