滑动窗口
作者:互联网
1.解决的问题:
一个数组中,其左右边界都可以向右滑动,根据窗口的左右边界滑动更新该窗口内的最大值(时间复杂度为O(1))
2.实现思路:
使用一个双端队列来维护:(处理的数据是数组的下标,而不是数本身)
* 1.对于右边界向右滑动一格,如果新增进来的元素比双端队列的队尾元素小,则直接加入。否则,则弹出当前队尾元素,
* 直到新增进来的元素小于队尾元素为止。
* 2.对于左边界向左滑动一格,如果被移走的左边界元素是队头元素,则弹出该队头元素。否则,不进行任何操作
3.代码实现:
1 public static class WindowMax{ 2 private int L; 3 private int R; 4 private int[] arr;//arr[L...R] 5 private LinkedList<Integer> qmax; 6 7 public WindowMax(int[] a) { 8 arr = a; 9 L = -1; 10 R = 0; 11 qmax = new LinkedList<>(); 12 } 13 14 public void addNumFromRight() { 15 if (R == arr.length) { 16 return; 17 } 18 while (!qmax.isEmpty() && arr[R] >= arr[qmax.peekLast()]) { 19 qmax.pollLast(); 20 } 21 qmax.addLast(R); 22 R++; 23 } 24 25 public void removeNumFromLeft() { 26 if (L >= R - 1) { 27 return; 28 } 29 L++; 30 if (L == qmax.peekFirst()) { 31 qmax.pollFirst(); 32 } 33 } 34 35 public Integer getMax() { 36 if (!qmax.isEmpty()) { 37 return arr[qmax.peekFirst()]; 38 } 39 return null; 40 } 41 }
4.运用该结构解决一个特例问题:
给定一个数组arr,窗口长度为3,从第一格开始依次向右移动,求出每次移动的窗口的最大值,最终结果用一个数组表示
代码:
1 public static int[] getWindowResult(int[] arr) { 2 WindowMax window = new WindowMax(arr); 3 for (int i = 0; i < 3; i++) { 4 window.addNumFromRight(); 5 } 6 int[] result = new int[arr.length - 2]; 7 for (int i = 0; i < arr.length - 2; i++) { 8 result[i] = window.getMax(); 9 window.addNumFromRight(); 10 window.removeNumFromLeft(); 11 } 12 return result; 13 }
标签:arr,窗口,int,qmax,return,window,滑动,public 来源: https://www.cnblogs.com/jue1e0/p/16225743.html