LeetCode.239. 滑动窗口最大值

74 阅读1分钟

题目


image.png

思路


  • 滑动窗口、优先队列
  • 滑动窗口负责维护固定的宽度,优先队列维护当前窗口内的元素,队首为所有元素的最大值,每次取这个最大值加入结果集

代码


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;
    }
};

总结


最重要的地方在于:

  • 我们期望滑动窗口向右滑动的时候,优先队列内的值能够实时更新,即窗口右移,左边元素应该从优先队列中移除,这是个可行的方法,只不过效率不够好
  • 简洁的方法是,每次只关注队首元素,即最大值,判断该最大值是否合法:该最大值是否处于当前窗口内,不处于则说明是前面步骤应该删除的元素,所以,优先队列可以存储元素的下标,方便判断元素是否位于当前窗口内部