import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
//1,暴力算法运行超时
/*
ArrayList<Integer> res = new ArrayList<>();
for (int i = 0; i < num.length-size+1; i++) {
int max = num[i];
for (int j = i; j < i+size; j++) {
max = max<num[j]?num[j]:max;
}
res.add(max);
}
return res;
*/
//2.双指针+双层遍历 运行超时
/*
ArrayList<Integer> res = new ArrayList<>();
if(num.length<size || num == null || size<1){
return res;
}
int left = 0,right = 0;
while (left+size<=num.length){
right = left+size-1;
int max = Integer.MIN_VALUE;
for (int i = left; i <= right; i++) {
max = max>num[i]?max:num[i];
}
res.add(max);
left++;
}
return res;
*/
//3。最大堆求解 运行超时
/*
PriorityQueue<Integer> maxQueue = new PriorityQueue<Integer>((o1, o2)->o2-o1);//大顶堆
ArrayList<Integer> result = new ArrayList<Integer>();//保存结果
if(num==null || num.length<=0 || size<=0 || size>num.length){
return result;
}
int count=0;
for(;count<size;count++){//初始化滑动窗口
maxQueue.offer(num[count]);
}
while(count<num.length){//对每次操作,找到最大值(用优先队列的大顶堆),然后向后滑动(出堆一个,入堆一个)
result.add(maxQueue.peek());
maxQueue.remove(num[count-size]);
maxQueue.add(num[count]);
count++;
}
result.add(maxQueue.peek());//最后一次入堆后没保存结果,这里额外做一次即可
return result;
*/
//4.单调队列
ArrayList<Integer> res = new ArrayList<>();
if(num.length<=0 || num.length<size || size<1){
return res;
}
Deque<Integer> q = new LinkedList<>();
for (int i = 0; i < num.length; i++) {
//q中存储当前滑动窗口的值在数组中的下标
if(q.isEmpty()){
q.add(i);
}else if(i-size+1>q.peekFirst()){//当q中存储窗口大小大于滑动窗口大小时,弹出队列首部的元素。
q.pollFirst();
}
while (!q.isEmpty() && num[i]>=num[q.peekLast()]){//若当前队列不为空,
// 且数组当前值大于队列中存储的最末段值,则弹出数组最末的元素
q.pollLast();
}
q.add(i);
if(i-size+1>=0){
res.add(num[q.peekFirst()]);
}
}
return res;
}
}