【剑指offer】滑动窗口的最大值

题目链接:滑动窗口的最大值

 

题意:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1},

 

题解:

1、首先想到的还是暴力。。。每次加入一个,判断一下当前的最大值。

2、这里正解应该是双端队列。参考了一下讨论区大佬的回答。

大概就是每次窗口里移走比当前出现值小的元素。保证最大值出现在队头。

判断滑动窗口是否包括数字,则是存储队列的下标。当某数字下标与当前数字的下标之差大于或者相等于size时,这个数字已经滑出,可以删除。

 

代码:

 1 class Solution {
 2 public:
 3     vector<int> maxInWindows(const vector<int>& num, unsigned int size){
 4         vector<int> ans;
 5         int len = num.size();
 6         if(len <=0 || size <= 0)    return ans;
 7         int start = 0; int end = size-1;
 8         while(end < len){
 9             ans.push_back(getMax(start,end,num));
10             start++;end++;
11         }
12         return ans;
13     }
14     int getMax(int start,int end ,const vector<int> &num){
15         int max = num[start];
16         for(int i = start+1 ; i <= end; i++){
17             if(num[i] > max)    max = num[i];
18         }
19         return max;
20     }
21 };
22 
23 
24 OR 
25 
26 
27 class Solution {
28 public:
29     vector<int> maxInWindows(const vector<int>& num, unsigned int size){
30         vector<int> ans;
31         deque<int> q;    //存储num下标
32         int len = num.size();
33         for(int i = 0; i < len ;i++){
34             //弹出队尾比当前值小的元素
35             while(!q.empty() && num[q.back()] <= num[i])    
36                 q.pop_back();
37             //当前窗口移动,即移出队首元素的位置
38             if(!q.empty() && (i-q.front()+1 > size))
39                 q.pop_front();
40             q.push_back(i);    //加入滑动的下标
41             if(size && (i+1 >= size))//滑动的首地址下标大于size才写入。
42                 ans.push_back(num[q.front()]);
43         }
44         return ans;
45     }
46 };

 

posted @ 2020-03-05 23:58  甜酒果。  阅读(160)  评论(0编辑  收藏  举报