• 栈和队列:生成窗口最大值数组


    题目:有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右滑一个位置。

    例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时:

    如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值。

    请实现一个函数:

    输入:整型数组arr,窗口大小为w。

    输出:一个长度为n-w+1的数组res,res[i]表示每个窗口状态下的最大值。

    以本题为例,结果应该返回{5,5,5,4,6,7}。

    如果暴力求解时间复杂度为 O(N x w),这个结果显然不能让人满意,这里我们将介绍复杂度为 O(N)的解法。

    本题的关键在于利于双端队列来实现窗口最大值的更新。首先生成双端队列 qmax,qmax中存放数组 arr 中的下标。

    假设遍历 arr[i],qmax 的放入规则为:

    1. 如果 qmax 为空,直接把下标 i 放入 qmax;

    2. 如果qmax不为空,取出当前 qmax 队尾存放的下标,假设为 j,

    a. 如果arr[j] > arr[i],直接把下标放入 qmax 的对尾

    b. arr[j] <= arr[j],把 j 从 qmax 中弹出,继续 qmax 的放入规则

    假设遍历到 arr[i],qmax 的弹出规则为:

    如果 qmax 队头的下标等于 i-w,说明当前 qmax 队头的下标已经过期,弹出当前队头的下标即可。

    根据上述放入和弹出规则,qmax便成了一个维护窗口为 w 的子数组的最大更新的结构。

    下面举例说明给出的例子。

     1     public static int[] getMaxWindow(int[] arr, int w)
     2     {
     3         if(arr == null || w < 1 || arr.length < w)
     4             return null;
     5 
     6         Deque<Integer> qmax = new LinkedList<Integer>();
     7         int[] res = new int[arr.length - w + 1];
     8         int index = 0;
     9         for(int i = 0; i < arr.length; i++)
    10         {
    11             while(!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[i])
    12             {
    13                 qmax.pollLast();
    14             }
    15             qmax.addLast(i);
    16             if(i - w == qmax.peekFirst())
    17                 qmax.pollFirst();
    18             if(i >= w - 1)
    19                 res[index++] = arr[qmax.peekFirst()];
    20         }
    21 
    22         return res;
    23     }

    参考:程序员代码面试指南 IT名企算法与数据结构题目最优解,左程云

  • 相关阅读:
    防F12审查元素扒代码:按下F12关闭当前页面
    Wp-UserAgent——让WordPress在评论后面加上浏览器和操作系统信息
    WordPress中添加自定义评论表情包的方法
    WordPress彩色背景标签云实现
    让wordpress标签云显示文章数的正确方法
    如何在WordPress文本小工具中使用PHP
    WordPress非插件实现评论回复邮件提醒通知
    Firefox取消“订阅实时书签”功能
    WordPress修改标签云大小及颜色
    WordPress菜单“显示选项”无法显示的解决办法
  • 原文地址:https://www.cnblogs.com/2015110615L/p/6659288.html
Copyright © 2020-2023  润新知