分享一个我认为空间复杂度和时间复杂度均比较不错的解法。原理很简单其实只分两步,第一,每次滑动窗口新进来的元素如果已经大于目前已经的窗口,则把最大值标记标成新进来的元素的索引值,ArrayList中添加当前最大值标记对应的数值,继续循环;第二,如果第一步没有发生(新进来的数没那么大),并且滑动窗口造成了把上一次的最大值标记给滑出去了,那么就需要重新找当前窗口的最大值了,找到后标记做新的最大值标记,ArrayList中添加当前最大值标记对应的数值,继续循环;第三,如果上述两件事均没发生,那现在的最大值肯定是暂时没变化的,直接添加旧的最大值标记对应的数值,继续循环,即可。

public ArrayList<Integer> maxInWindows(int [] num, int size){            

ArrayList<Integer> res = new ArrayList<Integer>();
if(size>num.length||num.length==0||size==0) return res;
int start=0,end=size-1,maxflag=searchMax(num, start, end);
for(;end<num.length;end++,start++) {
    if(num[end]>num[maxflag]) {
            maxflag=end;
            res.add(num[maxflag]);            
            continue;
        }
    if(start>maxflag) {
            maxflag=searchMax(num, start, end);
            res.add(num[maxflag]);
            continue;
        }            
  res.add(num[maxflag]);
    }
    return res;

}

private int searchMax(int [] num,int start,int end) {
    int flag=start;
    int max=num[start];
    while(start<=end) {
        if(num[start]>max) {
            flag=start;
            max=num[start];
        }
        start++;
    }
    return flag;
}