题目:
代码实现
将代码分为未形成窗口,和形成窗口后两部分:
public class MaxSlidingWindow {
public static void main(String[] args) {
MaxSlidingWindow window = new MaxSlidingWindow();
int[] nums = {1,3,-1,-3,5,3,6,7};
int k = 3;
System.out.println(Arrays.toString(window.maxSlidingWindow(nums, k)));
}
public int[] maxSlidingWindow(int[] nums, int k) {
//单调队列
//维护一个双端队列,对头是最大值,新元素放入队尾并循环比较放之前的队尾元素的大小,把比自己小的移除掉在加入队尾。
int len = nums.length;
Deque<Integer> deque = new LinkedList<>();
for (int i = 0; i < k; i++) { // 未形成窗口
while (!deque.isEmpty() && nums[deque.peekLast()] <= nums[i]) {//新元素放入队尾并循环比较放之前的队尾元素的大小,把比自己小的移除掉在加入队尾。
deque.pollLast();
}
deque.offerLast(i);
}
//定义结果数据
int r[] = new int[len-k+1];
r[0] = nums[deque.peekFirst()];
for (int i = k; i < len; i++) { //形成窗口后,窗口开始右移
while (!deque.isEmpty() && nums[deque.peekLast()] <= nums[i]) {//新元素放入队尾并循环比较放之前的队尾元素的大小,把比自己小的移除掉在加入队尾。
deque.pollLast();
}
deque.offerLast(i);
while (deque.peekFirst()<=i-k) { // 超过了窗口左侧,需要弹出
deque.pollFirst();
}
r[i-k+1] = nums[deque.peekFirst()];
}
return r;
}
}