题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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.multiset,底层红黑树 O(nlogn),小心这个容器的删除erase()方法。
2.deque 双端队列 O(n)
3.大顶堆 O(nlongn) 利用priority_queue<MyPair>实现。
解法一:最low ,注意我标注的删除。
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
multiset<int> myset;
vector<int> res;
if(num.empty()||size<1) return res;//没有这句话,又是非法访问,段错误。
for (int i = 0; i < num.size(); ++i)
{
if(myset.size()<size){
myset.insert(num[i]);
}
if(myset.size()==size){
multiset<int>::reverse_iterator it=myset.rbegin();
res.push_back(*it);
//myset.erase(num[i-size+1]);//multiset,一次删除操作可以删除多了相同的值。
//比如现在multiset里是{10 20 30 40 40 40 50 60},如果使用erase(40)的话,会把所有的40都删除了,得到{10 20 30 50 60}
multiset<int>::iterator itdel=myset.find(num[i-size+1]);
myset.erase(itdel);//这里删除的是某一个迭代器,而不是value=*itdel的所有值,所以这种方法可以只删除一个。
}
}
return res;
}
};
解法二:best
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> res;
if(num.empty()||size<1) return res;//又是没有这句话,说我内存爆炸了?
deque<int> indexdq;
for (int i = 0; i < size-1; ++i)
{
while(!indexdq.empty()&&num[indexdq.back()]<num[i]){//There must be while,not if,注意这是back()不是front()
indexdq.pop_back();
}
indexdq.push_back(i);
}
for (int i = size-1; i < num.size(); ++i)
{
while(!indexdq.empty()&&num[indexdq.back()]<num[i]){
indexdq.pop_back();//注意这里是pop_back()而不是pop_front()
}
indexdq.push_back(i);
if(i-indexdq.front()<size){
res.push_back(num[indexdq.front()]);
}else{
indexdq.pop_front();
res.push_back(num[indexdq.front()]);//注意这里不要遗漏,就算最大值弹出了,新的最大值.
}
}
return res;
}
};
解法三:还不错。
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> res;
if(num.empty()||size<1) return res;//又是没有这句话,说我内存爆炸了?
typedef pair<int,int> MyPair;
priority_queue<MyPair> maxheap;//优先级队列,默认为大顶堆。
for (int i = 0; i <size-1; ++i)
{
maxheap.push(MyPair(num[i],i));
}
for (int i = size-1; i < num.size(); ++i)
{
maxheap.push(MyPair(num[i],i));
MyPair top=maxheap.top();
while(i-top.second>=size){
maxheap.pop();
top=maxheap.top();
}
res.push_back(top.first);
}
return res;
}
};