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


    题目:有一个整型数组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名企算法与数据结构题目最优解,左程云

  • 相关阅读:
    我的第一次面试 —— 腾讯 AI安全 一面总结
    从零开始openGL——五、光线追踪
    从零开始openGL——四、纹理贴图与n次B样条曲线
    从零开始openGL——三、模型加载及鼠标交互实现
    从零开始openGL—— 二、 基本图形绘制
    NN入门,手把手教你用Numpy手撕NN(三)
    2020计算机保研经验分享
    TCP实战二(半连接队列、全连接队列)
    TCP实战一(三握四挥、流量控制)
    tcpdump抓包工具的基本使用
  • 原文地址:https://www.cnblogs.com/2015110615L/p/6659288.html
Copyright © 2020-2023  润新知