• 剑指offer系列53:滑动窗口的最大值


    分两步:

    首先找到窗口内的内容,然后找到窗口内的最大值。

     1 class Solution {
     2 public:
     3     vector<int> maxInWindows(const vector<int>& num, unsigned int size)
     4     {
     5         vector<int> re;
     6     
     7         int len = num.size();
     8         if (size == 0 || len == 0 || size > len)
     9             return re;
    10         //找到这几个数
    11         for (int i = 0; i <= len - size; i++)
    12         {
    13 
    14             re.push_back(findbig(num, size,i));
    15         }
    16         return re;
    17         //求这几个数中的最大值
    18     }
    19     int findbig(const vector<int>& num, unsigned int size, unsigned int i)
    20     {
    21         int big = num[i];
    22         for (int k=i+1;k<i+size;k++)
    23         {
    24             if (num[k] > big)
    25                 big = num[k];
    26         }
    27         return big;
    28     }
    29 };

    上面的解法是我自己想的,看了剑指offer,这个题是在栈与队列这一节放的,也就是考点是栈与队列。用上面的方法做时间复杂度是O(nk),但是用队列的方法做复杂度可以到O(n),也就是说每次滑动窗口可以在O(1)里找到最大值。

    很大提高了效率,那么怎么做呢。首先要想到队列这个数据结构,这个问题可以这样考虑:

    1.设计一个队列放窗口内的内容,滑动一下窗口,往队列后面加元素,尾部插入

    2.如果插入的这个结点比队列中原来的结点的尾部(不从头结点开始比较是因为头结点存的是最大的元素)的一些元素大,则删除这些尾部的元素,尾部删除

    3.如果头结点存的值是已经滑过去的窗口的值,则删掉。头部删除

    通过以上分析,头尾部都要操作,所以可以想到使用队列。

    然后就是如何用队列实现这个问题:

    1.对于不超过窗口长度的元素,只需要判断1,2

    2.对于后面的元素,需要判断1,2,3

     1 class Solution {
     2 public:
     3     vector<int> maxInWindows(const vector<int>& num, unsigned int size)
     4     {
     5         vector<int> re;
     6 
     7         int len = num.size();
     8         if (size == 0 || len == 0 || size > len)
     9             return re;
    10         deque<int> aux;
    11         for(int i=0;i<size;i++)
    12         {
    13             if (!aux.empty() && num[i] > num[aux.back()])//队列不为空并且来的元素大于以队列尾部的下标的值
    14                 aux.pop_back();
    15             aux.push_back(i);//队列中只存下标
    16         }
    17         for (int i = size; i < len; i++)
    18         {
    19             re.push_back(num[aux.front()]);
    20             while(!aux.empty() && num[i] > num[aux.back()])
    21                 aux.pop_back();
    22 
    23             
    24             if (!aux.empty() && aux.front() <= i - size)//队列最前面的值,也就是说最小的下标,不能是滑过的窗口元素
    25             {
    26                 aux.pop_front();
    27             }
    28             aux.push_back(i);
    29         }
    30         re.push_back(num[aux.front()]);
    31         return re;
    32     }
    33 };

    这个题首先要想到合适的数据结构,然后如何用这个合适的数据结构将这个题表达出来。都是需要考虑到的。

  • 相关阅读:
    再战CS231-数组的访问
    win10定时关机
    再战CS231-快速排序
    数据库权限
    numpy
    anaconda
    控件的相对位置与绝对位置-UI界面编辑器(SkinStudio)教程
    共用字体-UI界面编辑器(SkinStudio)教程
    添加图片按钮-UI界面编辑器(SkinStudio)教程
    为窗体设置背景图片-UI界面编辑器(SkinStudio)教程
  • 原文地址:https://www.cnblogs.com/neverland0718/p/11266336.html
Copyright © 2020-2023  润新知