单调队列:队列元素之间的关系具有单调性(从队首到队尾单调递增/递减),队首与队尾进行插入与删除操作,使队列保持单调递增/递减,由双端队列deque实现。
通过例题对单调队列进行分析掌握:
使用单调队列解决上述问题,基本思路:
1.创建一个单调队列,遍历nums数组生成不同的滑动窗口。
2.首先判断滑动窗口中的元素是否满足单调递减的特性,如果不满足,则反复删除队首元素,直到满足单调递减特性,此时使用peekFirst()方法获取队首即队列中的最大值。
3.再创建一个结果数组,将每个窗口中的最大值(每个队列中的第一个元素)依次添加到结果数组中。
4.每次滑动窗口前需将队列中第一个元素与窗口第一个元素进行比较,如果相等则使用pollFirst()方法将队列中第一个元素删除,确保窗口中元素的数量不变。
5.每次滑动窗口需添加nums数组中下一个元素到队列中。
代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
//创建队列
Deque<Integer> deque = new LinkedList();
//创建结果数组
int[] result = new int[nums.length-k+1];
//nums数组循环
for(int j=0,i=1-k;j<nums.length;i++,j++){
//删除deque中对应的nums[i-1](滑动窗口时将窗口第一个元素删除)
if(i>0 && deque.peekFirst() == nums[i-1]){ //i=2
deque.pollFirst();
}
//判断队列不为空,并且当数组下一个元素大于队尾(最小值)时,循环删除队尾元素,直到队列单调递减
while(!deque.isEmpty() && nums[j] > deque.peekLast()){
deque.pollLast();
}
//将数组下一个元素添加到队尾
deque.addLast(nums[j]);
//每一次滑动窗口,将队列中的队首元素(最大值)添加到结果数组
if(i >= 0){
result[i] = deque.peekFirst();
}
}
return result;
}
}