239. 滑动窗口最大值

滑动窗口的最大值

解题思路:

使用单调的双端队列,可以实现滑动窗口最大值的   O(n)的时间复杂度

 public static void main(String[] args) {
        /** 数组 */
        int[] arr={1,3,-1,-3,5,3,6,7};
        /** 滑动窗口的大小 */
        int k=3;

//        int[] arr={1,-1};
//        int k=1;
        int[] tagerArr = maxSlidingWindow(arr, k);
        System.out.println(Arrays.toString(tagerArr));
    }

    /**
     * @Description: 获得窗口中最大值
     * 使用单调的双端队列  队列中从队头到队尾 值有大到小  对头始终是窗口中的最大值
     * 使用单调的双端队列保证每次获得窗口中的最大值的时间复杂度是O(1)
     *  最终的时间复杂度是O(N)
     *
     *
     * @param nums 数组
     * @param k  窗口大小
     * @Date: 2020/6/16 13:09
     * @Author: fuGuoWen
     * @Return int[] 目标数组
     * @Throws 无
     */
    public static int[] maxSlidingWindow(int[] nums, int k) {
        /** linkedList 是双向链表 */
        LinkedList qmax = new LinkedList<>();
        /** 记录目标数组的长度 */
        int[] arr = new int[nums.length - k + 1];
        int index = 0;
        for (int i = 0; i < nums.length; i++) {
            /** 判断双向链表是否为空 */
            if (qmax.isEmpty()) {
                qmax.add(i);
            } else {
                /** 如果队列不为空,记录双向链表的末尾的值是否大于当前元素的值,
                 * 如果大于,直接加入双向链表中,如果小于,弹出对应的元素, 
                 * 直到找到对应的元素比当前元素大,加入到双向队列中
                 * */
                while (!qmax.isEmpty() && nums[qmax.getLast()] < nums[i]) {
                    qmax.pollLast();
                }
                qmax.add(i);
            }
            //5 4 3 3 最后一个3,把队头的5删除
            /** 如果已经超过窗口的长度,把双向队列的头部弹出 */
            if (!qmax.isEmpty() && qmax.getFirst() == i - k) {
                qmax.pollFirst();
            }
            /** 从下标为k-1 开始加入数组中 */
            if (i >= k - 1) {
                arr[index++] = nums[qmax.getFirst()];
            }
        }
        return arr;
    }

 

你可能感兴趣的:(LeetCode)