剑指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 };

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

posted @ 2019-07-29 20:37  妮妮熊  阅读(81)  评论(0编辑  收藏  举报