题目
思路
- 滑动窗口、优先队列
- 滑动窗口负责维护固定的宽度,优先队列维护当前窗口内的元素,队首为所有元素的最大值,每次取这个最大值加入结果集
代码
class Solution
{
public:
struct cmper
{
bool operator()(pair<int,int>& p1,pair<int,int>& p2)//自定义排序,用于优先队列的大根堆
{
return p1.first <= p2.first;
}
};
vector<int> maxSlidingWindow(vector<int>& a, int k)
{
priority_queue<pair<int,int>,vector<pair<int,int>>,cmper> q;
vector<int> ret;
auto n = a.size();
for(int i=0;i<k;i++)
{
q.push({a[i],i});
}
ret.push_back(q.top().first);
for(int R=k;R<n;R++)
{
q.push({a[R],R});
while(!q.empty() && q.top().second<=(R-k))
{
q.pop();
}
ret.push_back(q.top().first);
}
return ret;
}
};
总结
最重要的地方在于:
- 我们期望滑动窗口向右滑动的时候,优先队列内的值能够实时更新,即窗口右移,左边元素应该从优先队列中移除,这是个可行的方法,只不过效率不够好
- 简洁的方法是,每次只关注队首元素,即最大值,判断该最大值是否合法:该最大值是否处于当前窗口内,不处于则说明是前面步骤应该删除的元素,所以,优先队列可以存储元素的下标,方便判断元素是否位于当前窗口内部