LeetCode HOT100 - 滑动窗口最大值

滑动窗口移动的过程就是不断有元素进/出的过程

要维护这个过程中现有元素的最大值

那最基础的就是维护一个元素有没有出现

但是一个窗口中可能有多个相同元素,因此再加上元素的出现次数

因此一个数组来维护出现次数,一个优先队列来维护现有元素

每次移动同步对元素进行更新维护

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& a, int k) {
        unordered_map<int, int> cnt;
        priority_queue<int, vector<int>> pq;
        for (int i = 0; i < k; i++) {
            cnt[a[i]]++;
            if (cnt[a[i]] == 1) {
                pq.push(a[i]);
            }
        }
        int n = a.size();
        vector<int> ans;
        ans.emplace_back(pq.top());
        for (int l = 0, r = k; r < n; l++, r++) {
            cnt[a[l]]--;
            cnt[a[r]]++;
            if (cnt[a[r]] == 1) {
                pq.emplace(a[r]);
            }
            while (!pq.empty() && cnt[pq.top()] == 0) {
                pq.pop();
            }
            ans.emplace_back(pq.top());
        }
        return ans;
    }
};

正解是双端队列

同样还是考虑我们要什么

我们要的是区间中元素的最大值

我们前面用的是优先队列

但这样需要额外维护次数

因为我们每次插入的时候是把元素交给优先队列处理的,因而丢失了位置信息,所以要通过这种压缩的出现次数来判断是否还在窗口中

那如果我们直接从位置信息,也就是下标入手呢

下标不在窗口区间中那么就是被排除了

这样的话或许自己编写 cmp 去做下标的优先队列也是可行的,就是存下标,但比较比的是下标对应元素的大小

进一步考虑有其他方法吗

优先队列可以看作是维护了一个有序的数组

那我们能不能自己显式地把这个数组刻画出来呢

参考单调栈的想法

做一个单调队列

区别在于,我们这里队列头的元素最大

队列尾的元素最新,这里有些贪心的想法在,新加入的元素是最新的,比它小的元素一定不会在更远的滑动窗口中做出贡献,所以直接删除

题解一部分参考
https://leetcode.cn/problems/sliding-window-maximum/solutions/5458/shuang-xiang-dui-lie-jie-jue-hua-dong-chuang-kou-z

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& a, int k) {
        vector<int> ans;
        deque<int> q;
        int n = a.size();
        for (int i = 0; i < k; i++) {
            while (!q.empty() && a[i] > a[q.back()]) {
                q.pop_back();
            }
            q.emplace_back(i);
        }
        ans.emplace_back(a[q.front()]);
        for (int i = k; i < n; i++) {
            while (!q.empty() && q.front() <= i - k) {
                q.pop_front();
            }
            while (!q.empty() && a[i] > a[q.back()]) {
                q.pop_back();
            }
            q.emplace_back(i);
            ans.emplace_back(a[q.front()]);
        }
        return ans;
    }
};
posted @ 2026-04-08 23:50  rdcamelot  阅读(14)  评论(0)    收藏  举报