给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。
一、使用双向队列
https://www.cnblogs.com/CarpenterLee/p/5468803.html
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> res=new ArrayList<>();
if(size==0)
return res;
int begin;
ArrayDeque<Integer> q=new ArrayDeque<>();
for(int i=0;i<num.length;i++){
//begin保存滑动窗口首元素的下标
begin=i-size+1;
if(q.isEmpty())
//队列加入元素的下标
q.add(i);
else if(begin>q.peekFirst())//判断下标是否过期
q.pollFirst();
while(!q.isEmpty()&&num[q.peekLast()]<=num[i])//队尾放入大的元素
q.pollLast();
q.add(i);
if(begin>=0)
res.add(num[q.peekFirst()]);
}
return res;
}
}
二、使用大顶堆
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> res=new ArrayList<>();
if(size<1||size>num.length)
return res;
//大顶堆
PriorityQueue<Integer> heap=new PriorityQueue<>((o1,o2)-> o2-o1);
for(int i=0;i<size;i++){
heap.add(num[i]);
}
res.add(heap.peek());
//维护一个大小为size的大顶堆
for(int i=0,j=i+size;j<num.length;i++,j++){
heap.remove(num[i]);
heap.add(num[j]);
res.add(heap.peek());
}
return res;
}
}