/*!
* @file 滑动窗口的最大值.cpp
* @Date: 2018/03/20 21:32
* @author: sicaolong
* @Contact: sicaolong@163.com
* @brief:
思想:
1、当当前的元素数位size时候,不需要移动操作,只比较新元素的大小与队列的最大值得比较;
2、当当前的元素数大于size的时候要进行 deque.pop_back();将队头的弹出队列,
3、重点是 新元素与窗口中的最大值比较,大于的话,将队列清空,将新元素的下标压入,否则的话,仅仅是弹出队头;
最后将最大值压入一个新的vector;
* @TODO:
*/
// 面试题59(一):滑动窗口的最大值
// 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,
// 如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个
// 滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5},
#include<iostream>
#include <vector>
#include<deque>
using namespace std;
vector<int> get_max_in_windows(const vector<int >&num, unsigned int size);
//=========main函数
int main()
{
vector<int> num = { 2, 3, 4, 2, 6, 2, 5, 1 };
vector<int>max = get_max_in_windows(num, 3);
for (int i = 0; i < max.size(); ++i)
{
cout << max[i] << " ";
}
cout << endl;
}
vector<int> get_max_in_windows(const vector<int >&num, unsigned int size)
{
vector<int> max_in_windows;//窗口中的最大值 容器
if (num.size() < size || size <= 0)//非法的输入;
return max_in_windows;
//vector<int> max_in_windows;
deque<int>index;
for (int i = 0; i < size; i++)//在前size个数的时候不需要进行移动;
{
while (!index.empty() && num[i]>num[index.back()])//当新元素大于队中的元素
index.pop_back();//队弹出;
index.push_back(i);//新元素的下标入队;
}
for (int i = size; i < num.size(); ++i)//在size个元素后 需要进行移动操作了
{
max_in_windows.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();//如果队头的下标超过size之后,应该将队头弹出;
index.push_back(i);//将新元素的下标入队;
}
max_in_windows.push_back(num[index.front()]);//将最大值 压入容器中
return max_in_windows;
}