栈和队列:leetcode no.239滑动窗口最大值

运用单调队列的知识点

最直接的做法就是暴力,就是每一个窗口都去遍历一遍窗口内的元素,找到其中的最大值。但很明显这样的时间复杂度是n * k。如果我们用单调队列的话那么只需要遍历一次数组即可,时间复杂度是n

我们要模拟一个队列,像题目中所描述的窗口一样在滑动的时候弹出队列前端的第一个元素同时队列后端入队一个元素。但是我们要获取这个窗口也就是队列的最大值,因此这个队列必须是单调的。但是这个队列不能是优先队列,因为优先队列排序后不能够模拟窗口移动时要移除的元素。

继续思考我们还会发现,在不改变元素的顺序时,是没有必要去维护当前窗口内最大元素外的其他元素的。

要实现单调队列,最重要的是解决每一道题目对应的条件。这道题目中推入元素时如果队尾的元素比此时的元素要小,则弹出队尾元素,直到队尾元素大于或等于此元素。同时每遍历到数组中第i个元素,要判断第i- k个元素是否位于上一个窗口前面,如果是则要弹出。这样才能模拟窗口移动时元素的移除方式同时对队列内的元素进行排序,保证此时窗口内最大的元素位于队列第一个。

代码实现:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> result;
        deque<int> w;
        int i = 0, j = k;
        for (i = 0; i < k; i++) {
            while (!w.empty() && w.back() < nums[i])
                w.pop_back();
            w.push_back(nums[i]);
        }
        result.push_back(w.front());
        for (; i < nums.size(); i++) {
            if (!w.empty() && w.front() == nums[i - k])
                w.pop_front();
            while (!w.empty() && w.back() < nums[i])
                w.pop_back();
            w.push_back(nums[i]);
            result.push_back(w.front());
        }
        return result;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值