题意
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
问题分析
单调队列
//C++
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
deque<int> dq;
int len = nums.size();
if(len == 0)
return res;
dq.push_back(nums[0]);
for(int i = 1; i < k; i++){
while(!dq.empty() && dq.back() < nums[i])
dq.pop_back();
dq.push_back(nums[i]);
}
res.push_back(dq.front());
for(int i = k; i < len; i++){
if(nums[i-k] == dq.front()) dq.pop_front();
while(!dq.empty() && dq.back() < nums[i]) dq.pop_back();
dq.push_back(nums[i]);
res.push_back(dq.front());
}
return res;
}
};
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0 || k == 0) return new int[0];
Deque<Integer> deque = new LinkedList<>();
int[] res = new int[nums.length - k + 1];
for(int j = 0, i = 1 - k; j < nums.length; i++, j++) {
if(i > 0 && deque.peekFirst() == nums[i - 1])
deque.removeFirst(); // 删除 deque 中对应的 nums[i-1]
while(!deque.isEmpty() && deque.peekLast() < nums[j])
deque.removeLast(); // 保持 deque 递减
deque.addLast(nums[j]);
if(i >= 0)
res[i] = deque.peekFirst(); // 记录窗口最大值
}
return res;
}
}
也可以像《剑指Offer》中一样,双端队列保存的是数组的索引,这样在判断最大值是否左移出队方便一些