6、C++算法之代码随想录(栈和队列)——滑动窗口最大值

(1)问题

        力扣——239. 滑动窗口最大值 - 力扣(LeetCode)

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
(2)思路

        使用队列来存储窗口中的元素,随着窗口移动,队列元素也不断插入和移除。然后每次寻找队列的最大值。但这样的时间复杂度为O(n*k)。如何用线性的时间解决该问题,就需要使用到单调队列,将窗口的最大值维护在队列首。这样每次就能直接获取当前窗口的最大值了。 那么这个单调队列就需要自己定义其功能。主要是插入、移除和返回队列首元素三个功能。

        插入:如果插入元素大于队列尾元素,就删除队尾元素。然后再插入。

        移除:如果移除的元素等于当前队首元素,才移除,否则不进行移除。

        返回:返回队首元素。

自定义单调队列类的代码实现

class MyQueue{
public:
    deque<int> que;

    void push(int value)
    {
        while(!que.empty()&&value>que.back())
        {
            que.pop_back();
        }
        que.push_back(value);
    }

    void pop(int value)
    {
        if(!que.empty()&&value==que.front())
        {
            que.pop_front();
        }
    }

    int front()
    {
        return que.front();
    } 
};
(3)解题流程

        1.首先实例化自定义队列和创建结果数组。

        2.将前K个元素移入队列。

        3.将队首元素插入结果数组。

        4.遍历数组剩下的元素。不断插入和删除队列元素。并将队首元素存储到结果数组中。

        5.返回结果数组。

代码实现:

  vector<int> maxSlidingWindow(vector<int>& nums, int k) {

        vector<int> ans;
        MyQueue myqueue;

        for(int i=0;i<k;i++)
        {
            myqueue.push(nums[i]);
        }
        ans.push_back(myqueue.front());

        for(int i=k;i<nums.size();i++)
        {
            myqueue.pop(nums[i-k]);
            myqueue.push(nums[i]);
            ans.push_back(myqueue.front());
        }
        return ans;
    }

        这道题是使用单调队列的经典题目,单调队列并不是固定的。不同的题有不同的写法。只需要保证队列是单调递增或递减的即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值