本周两题均可使用双端队列
剑指 Offer 59 - I. 滑动窗口的最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums==null || nums.length<=0) return new int[0];
int start = 0, end = 0;
int[] res = new int[nums.length-k+1];
Deque<Integer> deque = new LinkedList<>();
while(end<k) { //滑动窗口未形成 只维护单调递减队列
while(deque.peekLast()!=null && deque.peekLast()<nums[end]) {
deque.removeLast();
}
deque.addLast(nums[end++]);
}
res[start++] = deque.peekFirst();
while(end<nums.length) { //滑动窗口初始化完成 开始右移
if(deque.peekFirst()==nums[start-1]) deque.removeFirst(); //判断队首是否出队
while(deque.peekLast()!=null && deque.peekLast()<nums[end]) {
deque.removeLast();
}
deque.addLast(nums[end++]);
res[start++] = deque.peekFirst();
}
return res;
}
}
剑指 Offer 59 - II. 队列的最大值
class MaxQueue {
private int[] nums;
private int start;
private int end;
private Deque<Integer> deque;
public MaxQueue() {
this.nums = new int[10000];
this.start = 0;
this.end = 0;
this.deque = new LinkedList<>();
}
public int max_value() {
Integer max = deque.peekFirst();
return max==null ? -1 : max;
}
public void push_back(int value) {
nums[end++] = value;
while(deque.peekLast()!=null && deque.peekLast()<value) {
deque.removeLast();
}
deque.addLast(value);
}
public int pop_front() {
if(start>=end) return -1;
int value = nums[start++];
if(value==deque.peekFirst()) {
deque.removeFirst();
}
return value;
}
}