点击关注公众号,干货第一时间送达

各位,请听题:

解题:
用双端队列!
队列 queue 保持递减序,则队头就是最大值,队尾就是最小值。
我们再控制住队列长度符合窗口值w大小,即可取出移动过程中每个窗口的最大值。
1,程序执行过程
遍历数组 arr,queue中存放arr数组下标。
如果 queue为空,则当前遍历i,直接入队尾;
如果 queue队尾对应数组值 arr[queue.peekLast] 小于当前遍历i的数组值arr[i]
则弹出队尾,直到队尾对应数组值大于 arr[i];
然后 i 加入队尾即可
如果队头值等于 i-w,则表示窗口移动过了,需要移除队头了。
2,流程如下图



依次类推,直到数组末尾。
3,完整代码
public class CodingDemo {
public static int[] getMaxWindowArr(int[] arr, int w){
if (arr == null || arr.length < w || w < 1){
return null;
}
//1,创建双端队列
LinkedList<Integer> queue = new LinkedList<Integer>();
//2,创建结果数组, 长度等于 arr.length-w+1,
//因为生成了 arr.length-w+1 个窗口
int[] res = new int[arr.length - w + 1];
int index = 0;
//3,开始遍历数组
for (int i = 0; i < arr.length; i++) {
//3.1 如果队尾对应值小于当前遍历值,则弹出队尾,直到队尾对应数组值大于当前值
while (!queue.isEmpty() && arr[queue.peekLast()] <= arr[i]){
queue.pollLast();
}
//3.2 加入当前 i
queue.addLast(i);
if (queue.peekFirst() == i-w){
queue.pollFirst();//窗口过期了,需要移除队头
}
//3.3 因为i从0开始,除了需要等待第一个窗口生成,
//后面每移动一步,都会有窗口,不需要等待
if (i+1 >= w){
res[index++] = arr[queue.peekFirst()];//记录此窗口最大值
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {4,3,5,4,3,3,6,7};
System.out.println(Arrays.toString(getMaxWindowArr(arr, 3)));
}
}
输出:
D:\java\bin\java.exe
[5, 5, 5, 4, 6, 7]

文章转载自皮皮克克,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




