题目:
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组{2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小为3,那么一共存在6个滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6 , 5}。
思路:
解法一:碰到这种题目首先想到的是,每次扫描每一个滑动窗口的所有数字并找出最大值。如果滑动窗口为 k,数组的元素有 n 个,那么时间复杂度为(kn)。
解法二:使用队列数据结构来保存滑动窗口的元素的下标,队列头部保存的是滑动窗口的最大值,每移动一个元素,则比较当前元素和队尾元素的大小,如果队尾元素比当前元素大,则移除队尾的元素,直到队列为空或者队列内的元素比当前元素大。具体的代码如下:
//
// Created by 陈国威 on 2018/6/15.
//
/*
* 题目:滑动窗口的最大值
* */
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> maxInWindows;
if (num.size() >= size && size >= 1)
{
deque<int> index;
// 刚开始输入 size 个元素
for (unsigned int i = 0; i < size; i++)
{
while (!index.empty () && num[i] >= num[index.back ()])
index.pop_back ();
index.push_back (i);
}
for (unsigned int i = size; i < num.size (); i++)
{
maxInWindows.push_back (num[index.front ()]);
while (!index.empty () && num[i] > num[index.back ()]) // 如果移动的当前元素比队列中的大,则移除队列中的元素
index.pop_back ();
if (!index.empty () && index.front () <= (int)(i - size)) // 如果当前队列头的元素滑出了窗口,则移除
index.pop_front ();
index.push_back (i);
}
maxInWindows.push_back (num[index.front ()]);
}
return maxInWindows;
}
参照:
《剑指offer》