题目:
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
思路:
借助双端队列,保存最大值相关信息
窗口右移时,若此时队列中最大值为窗口最左边,队列头出队;若最右边值比队列头大或者相等,则清空队列,新值入队列;否则将队列后面(队首除外)小于或者等于新值的数据出队,新值入队列
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> res;
if (num.size() < size || 0 == size)
return res;
deque<pair<int, int> > max_que;
int left = 0, right = 0;
max_que.push_back(pair<int, int>(num[0], 0));
//前size个数据入队列
for(right=1; right<size; right++)
{
int tmp = num[right];
if(tmp >= max_que.front().first)
{
deque<pair<int, int> >().swap(max_que);
max_que.push_back(pair<int, int>(tmp, right));
}
else
{
while(max_que.size() > 1 && tmp >= max_que.back().first)
{
max_que.pop_back();
}
max_que.push_back(pair<int, int>(tmp, right));
}
}
res.push_back(max_que.front().first);
--right;
//开始滑动窗口
for(;right<num.size()-1;++right,++left)
{
int tmp = num[right+1];
if(left == max_que.front().second)
max_que.pop_front();
if(tmp >= max_que.front().first)
{
deque<pair<int, int> >().swap(max_que);
max_que.push_back(pair<int, int>(tmp, right+1));
}
else
{
while(max_que.size() > 1 && tmp >= max_que.back().first)
{
max_que.pop_back();
}
max_que.push_back(pair<int, int>(tmp, right+1));
}
res.push_back(max_que.front().first);
}
return res;
}
};
//将上面代码稍微简化下
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> res;
if (num.size() < size || 0 == size)
return res;
deque<pair<int, int> > max_que;
max_que.push_back(pair<int, int>(num[0], 0));
for(int left = 0, right = 0; right<num.size(); ++right)
{
int tmp = num[right+1];
//此时窗口开始移动
if(size - 1 == right-left)
{
res.push_back(max_que.front().first);
if(left == max_que.front().second)
max_que.pop_front();
++left;
}
if(tmp >= max_que.front().first)
deque<pair<int, int> >().swap(max_que);
else
while(max_que.size() > 1 && tmp >= max_que.back().first)
max_que.pop_back();
max_que.push_back(pair<int, int>(tmp, right+1));
}
return res;
}
};