数据结构--窗口内最大值最小值的更新结构(单调双向队列)

窗口内最大值最小值的更新结构(单调双向队列)

 滑动窗口的最大值

窗口滑动的规则:

L,R开始均指向数组的最左边,L < R,

窗口内增加元素:R向右走,

窗口内减少元素:L向右走

R和L均不能向后退,只能向前走

 

数组array

采用双端链表LingkedList(双端队列)(index(在数组中的位置,可以用来表示过期没过期),value(在数组中的值)),链表内保证    尾进头出,且保证从头到尾是从大到小排序

当窗口内加数num时,从尾部进入,若尾部当前数大于num,则直接放入,若当前元素小于或等于num,则将其弹出,一直到满足其中的数大于num或者弹空了,保证降序排列。

当窗口减数num时,检查头部的数的index,如果是已经过期(即数组中该数不在窗口内)则从头部弹出

注:可以在双端队列中只存下标,因为可以从数组array中通过下标拿到值

 

 

 

生成窗口最大值数组
有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边, 窗口每次向右边滑一个位置。
例如, 数组为[4,3,5,4,3,3,6,7], 窗口大小为3时:
[4 3 5] 4 3 3 6 7 窗口中最大值为5
4 [3 5 4] 3 3 6 7 窗口中最大值为5
4 3 [5 4 3] 3 6 7 窗口中最大值为5
4 3 5 [4 3 3] 6 7 窗口中最大值为4
4 3 5 4 [3 3 6] 7 窗口中最大值为6
4 3 5 4 3 [3 6 7] 窗口中最大值为7
如果数组长度为n, 窗口大小为w, 则一共产生n-w+1个窗口的最大值。
请实现一个函数。
输入: 整型数组arr, 窗口大小为w。
输出: 一个长度为n-w+1的数组res, res[i]表示每一种窗口状态下的最大值。
以本题为例, 结果应该返回{5,5,5,4,6,7}。

 

public class SlidingWindowMaxArray {

    public static int[] getMaxWindow(int[] arrays, int k){
        if(arrays == null || arrays.length == 0) return null;
        LinkedList<Integer> list = new LinkedList<>();
        int[] res = new int[arrays.length - k + 1];
        int x = 0;
        for(int i = 0; i < arrays.length; i++){
            while(!list.isEmpty() && arrays[list.peekLast()] <= arrays[i]){
                list.pollLast();
            }
            list.addLast(i);
            //判断是否过期
            while(list.peekFirst() == i - k){
                list.pollFirst();
            }
            //窗口大小超过k
            if(i >= k - 1){
                res[x++] = arrays[list.peekFirst()];
            }
        }
        return res;
    }

    public static void printArray(int[] arr) {
        for (int i = 0; i != arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = { 4, 3, 5, 4, 3, 3, 6, 7 };
        int w = 3;
        printArray(getMaxWindow(arr, w));
    }
}

  

posted @ 2018-05-03 11:34  SkyeAngel  阅读(261)  评论(0编辑  收藏  举报