题目
方法一:优先队列
public class MaxSlidingWindow {
public int[] maxSlidingWindow(int[] nums, int k) {
//优先队列,堆顶即是最大值,每次移动需要考虑最大值是否还在滑动窗口内
PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]!=o2[0] ? o2[0]-o1[0] : o2[1]-o1[1];
}
});
int len = nums.length;
for (int i = 0; i < k; i++) {
queue.offer(new int[]{nums[i], i});
}
int[] r = new int[len - k + 1];
r[0] = queue.peek()[0];
for (int i = k; i < len; i++) {
queue.offer(new int[]{nums[i], i});
while (queue.peek()[1]<=i-k) {
queue.poll();
}
r[i-k+1] = queue.peek()[0];
}
return r;
}
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)));
}
}
LeetCode测试结果
方法二:单调队列
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;
}
}
LeetCode测试结果