----学习记录-----
滑动窗口最大值
本菜鸡接触的第一道hard题目。
这里提出了队列的一种新用法,单调队列。
也就是说队列要保证有序,根据本题我们选择构造一个单调减队列,这样就可以保证队列的队首永远都是最大值,方便后期取值。
队列没有必要存储窗口里的所有元素,只需要保证所有可能成为窗口内最大值的元素都存在即可。
在元素入列时有两种情况:
1.新加入的值大于队列中的某些值,这时将这些值全部出列,并将新值加入。(因为这些值的坐标都小于新加入的值,所以滑动窗口中只要存在这些值就一定会存在新加入的这个值,因此之后滑动窗口的最大值已经不可能是这些数,不需要对其进行保存)
2.新加入的值为最小的值,直接加入队列中。
每次在添加元素之后要判断队列队首的元素是否还在滑动窗口内,如果不在则将其出列。(保证队列队首为窗口内最大值)
//leetcode-239
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int []arr = new int[n - k + 1];
//队列要保证从大到小排序
Deque<Integer> queue = new LinkedList<>();
for(int i = 0; i < n; i++){
//如果新加入的值大于列表中的某些值,就将这些值全部出列,之后加入新的值
//因为这些值的坐标都小于新加入的值,所以滑动窗口中只要存在这些值就一定会存在新加入的这个值
//因此之后滑动窗口的最大值已经不可能是这些数了
while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){
queue.pollLast();
}
queue.addLast(i);
//如果当前列表最大值不在滑动窗口中就将其出列
if(queue.peekFirst() <= i - k){
queue.pollFirst();
}
if(i + 1 >= k){
arr[i - k + 1] = nums[queue.peekFirst()];
}
}
return arr;
}
}
未完待续。。。