剑指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}, {2,3,4,2,6,[2,5,1]}。
 

解题思路

 

考虑用一个双向队列来记录当前滑动窗口,保持队首为最大值的下标。首先把第一个滑动窗口中最大值的下标放入队列,然后从第二个窗口开始遍历数组:

  • 首先把队首下标值放入结果集中,此为上一个窗口最大值;
  • 接着从队尾开始向前依次比较,把小于当前数字以及不在当前窗口的下标从队列中删除;
  • 最后把此数字下标放入队列中

 

代码

 

 1 class Solution {
 2 public:
 3     vector<int> maxInWindows(const vector<int>& num, unsigned int size)
 4     {
 5         vector<int> v;
 6         if(num.size()>=size&&size>=1){
 7             deque<int> index;
 8             //队列中保留第一个窗口的最大值下标
 9             for(int i=0;i<size;i++){
10                 while(!index.empty()&&num[i]>=num[index.back()])
11                     index.pop_back();
12                 index.push_back(i);
13             }
14             for(int i=size;i<num.size();i++){
15                 v.push_back(num[index.front()]);
16                 while(!index.empty()&&num[i]>=num[index.back()])
17                     index.pop_back();
18                 if(!index.empty()&&index.front()<=i-size)
19                     index.pop_front();
20                 index.push_back(i);
21             }
22             v.push_back(num[index.front()]);
23         }
24         return v;
25     }
26 };

 

posted @ 2018-04-29 19:57  FlyingWarrior  阅读(156)  评论(0编辑  收藏  举报