滑动窗口之滑动窗口最大值

思路分析:

力扣https://leetcode-cn.com/problems/sliding-window-maximum/

  • 首先相同题目的比较,字符串和子字符串的相关题目是需要自己利用left、right指针来表示一个自适应的窗口,但是滑动窗口的最大值是不需要设置left、right指针的,直接设置了窗口的大小。所以在代码实现中直接利用if 先把窗口大小k-1进行 赋值,然后else进入窗口的滑动;
  •  实现单调队列实现在窗口内以O(1)的复杂度获取窗口中的队列
  • 「单调队列」数据结构解决滑动窗口问题

 利用单调队列作为窗口的实现,不断地压入元素到队列中,对头元素始终是最大值。

单调队列主要是解决push、pop的实现,以及实现获取队列中的max函数。

此处单调队列就是队列中的元素是呈降序排列的,每新添加进来一个元素,都会把它前面比它小的元素删除,从而保证队列的首元素是队列中最大值。

  C++实现单调队列版本

力扣https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/

class deque {
    // 在队头插入元素 n
    void push_front(int n);
    // 在队尾插入元素 n
    void push_back(int n);
    // 在队头删除元素
    void pop_front();
    // 在队尾删除元素
    void pop_back();
    // 返回队头元素
    int front();
    // 返回队尾元素
    int back();
}

 

完整代码实现

 注意单调队列的设计中push函数不能用等号,因为不然会把重复的大的值删除

 [-7,-8,7,5,7,1,6,0]  k=4

输出会编成[7,7,7,6,6]

而正解是[7,7,7,7,7]

class Solution {
public:

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        MonotonicQueue window;
        int i=0;
        while(i<nums.size()){
            if(i<k-1){//放进去num中比滑动窗口数量少一个的元素,这样就能和后面窗口的步骤对应起来
                window.push(nums[i]);
            }
            else{
                window.push(nums[i]);
                res.push_back(window.max());
                window.pop(nums[i-k+1]);
            }
            i++;
        }
        return res;

    }
    class MonotonicQueue{
public:
    deque<int> monotonicQueue;
    void push(int n){//关键的push函数怎么把要插入的比它笑的元素干掉
        while(!monotonicQueue.empty()&&monotonicQueue.back()<n)//!!!这里不能用等于,不然会把重复的元素也删除了
        {
            monotonicQueue.pop_back();
        }
        monotonicQueue.push_back(n);
    }

    void pop(int n){//删除队列窗口中的首元素,要先判断该队列表示的窗口中元素是否已经被删除,而且要想怎么表示窗口中的第一个元素
        if(!monotonicQueue.empty()&&monotonicQueue.front()==n)
            monotonicQueue.pop_front();
    }

    int max(){
        return monotonicQueue.front();
    }
        
};
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值