day15-239. 滑动窗口最大值

239. 滑动窗口最大值

力扣题目链接(opens new window)

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

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

思路

这道题我一开始的想法,就是用dequeue队列进行操作,用长度为k的队列遍历所有字符,然后每一次访问都进行一次排序,由此下来复杂度是O(n k),于是有了以下结果

在这里插入图片描述

代码大概如下(错误的,不要学)

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int>res;
        deque<int> q;
        for(int n:nums){
            if (q.size()<k){
                q.push_back(n);
            }else
            {
                int max = *max_element(q.begin(),q.end());
                res.push_back(max);
                q.pop_front();
                q.push_back(n);
            }
        }
        int max = *max_element(q.begin(),q.end());
        res.push_back(max);
        return res;
    }
};

肯定有更简单的做法,这这道题还是要用队列来做的,但是却不是普通的队列。

我们如果想要复杂度只有O(n),那便不能做排序的操作,而是将最大值放在队列头部,随取随用。要做到这个操作首先有两个步骤

  • 每次push时,将队列中小于当前值的元素pop掉
  • 每次pop时,如果pop的值与队列头部相等,则执行pop操作

这里的push为自定义的push,如果每次push都将比当前值下的元素值pop掉,那么队列的头部必定是最大值,这是毋庸置疑的。

而有了第一步的操作时,我们在pop时就需要加一个判断,如果与队列头部(也即队列最大值)相等,可以说明一件事情,就是在pop之前,队列没有进行任何pop的操作,压进来的第一个元素便是最大值,而且后续元素是递减排列,因此不用取pop。只有在这种情况下才需要pop,其他情况早已经在push时顺手pop掉了。

有了思路了就好操作了,代码如下:

class Solution {
private:
    class Myqueue{
    private:
        deque<int> myqueue;
    public:
        Myqueue(){}
        void push(int val){
            while(!myqueue.empty() && val > myqueue.back()){
                myqueue.pop_back();
            }
            myqueue.push_back(val);
        }
        void pop(int val){
            if (!myqueue.empty() && val == myqueue.front())
            {
                myqueue.pop_front();
            }

        }
        int get_maxVale(){
            return myqueue.front();
        }
    };
public:

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        Myqueue myqueue;
        for (int i = 0; i < k; ++i) {
           myqueue.push(nums[i]);
        }
        res.push_back(myqueue.get_maxVale());
        for (int i = k; i < nums.size(); ++i) {
            myqueue.pop(nums[i-k]);
            myqueue.push(nums[i]);
            res.push_back(myqueue.get_maxVale());
        }
        return res;
    }
};
        res.push_back(myqueue.get_maxVale());
    }
    return res;
}

};


你可能感兴趣的:(算法,算法,数据结构)