题目:
有一个整型数组arr,和一个大小为w的窗口从数组的最左边滑到最右边,数组每次向右边滑动一个位置。
例如[4,3,5],4,4,3,6,7
此时的窗口为3,当向右移动一个位置时即4,[3,5,4],4,3,6,7
一直到4,3,5,4,4,[3,6,7]这样
所以一个为n大小的数组,w为窗口大小,则一共产生n-w+1个窗口最大值。
给出一个数组arr,和w大小的窗口,求每个窗口下的最大值数组?
package Queue;
import java.util.LinkedList;
public class DoubleQueue {
public static void main(String[] args) {
int w = 3;
int[] b = {4,3,5,4,3,3,6,7};
int[]a = getMaxWindow(b,w);
for(int r:a) {
System.out.print(r+",");
}
}
public static int[] getMaxWindow(int[]arr,int w) {//参数为数组,和窗口的大小
if(arr==null||w<1||arr.length<w) {//若数组为空,w<1,或者窗口大于数组,则没法找出每组窗口最大值
return null;//返回null表示get结束
}
LinkedList<Integer> qmax = new LinkedList<Integer>();//用一个链表来模拟双端数组,用来存放符合标准的数组下标
int[]res = new int[arr.length-w+1];//新建一个int类型的数组用于存放每个窗口中的最大值
int index=0;//这个是用来res数组计数
for(int i = 0;i<arr.length;i++) {//遍历数组
while(!qmax.isEmpty()&&arr[qmax.peek()]<=arr[i]) {//当qmax为空并且qmax存放的第一个下标数组对应值(最大值)小于新值
qmax.pollLast();//将qmax中最后一个值弹出
}
qmax.addLast(i);//每次遍历都将i放入qmax的队尾
if(qmax.peekFirst()==i-w) {//这个用来防止qmax里面存的数过期,过期即指qmax队列的第一个下标不能等于遍历i-w,因为每次只能在窗口的范围内取值
qmax.pollFirst();//过期就将qmax队首元素弹出
}
if(i>=w-1){//如果i>w-1,即满足窗口大小,就将qmax队首下标数组对应的值放入res(此时对应的值为最大值)
res[index++]=arr[qmax.peekFirst()];
}
}
return res;
}
}
参考书籍:《程序员代码面试指南》