• 力扣第239题 c++滑动窗口经典题 单调队列


    题目

    239. 滑动窗口最大值

    困难

    提示

    队列 数组 滑动窗口 单调队列 堆(优先队列)

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

    返回 滑动窗口中的最大值 

    示例 1:

    输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
    输出:[3,3,5,5,6,7]
    解释:
    滑动窗口的位置                最大值
    ---------------               -----
    [1  3  -1] -3  5  3  6  7       3
     1 [3  -1  -3] 5  3  6  7       3
     1  3 [-1  -3  5] 3  6  7       5
     1  3  -1 [-3  5  3] 6  7       5
     1  3  -1  -3 [5  3  6] 7       6
     1  3  -1  -3  5 [3  6  7]      7
    

    示例 2:

    输入:nums = [1], k = 1
    输出:[1]
    

    提示:

    • 1 <= nums.length <= 105
    • -104 <= nums[i] <= 104
    • 1 <= k <= nums.length

    思路和解题方法

    1. 定义了一个名为Solution的类,其中包含了一个嵌套类myqueue
    2. myqueue类使用deque来实现一个单调队列,具有三个方法:poppushfront
    3. maxSlidingWindow方法接收一个整数数组nums和窗口大小k作为参数,用于求解滑动窗口的最大值。
    4. 在方法中,首先创建一个myqueue对象que,并将前k个元素依次插入队列中(通过调用myqueue类的push方法)。
    5. 然后将队列的首元素(即最大值)加入到结果向量ans中。
    6. 接下来,从第k个元素开始遍历数组nums,每次循环:
      • 先将窗口外的元素从队列中移出(通过调用myqueue类的pop方法)。
      • 然后将当前元素插入到队列中(通过调用myqueue类的push方法)。
      • 再将队列的首元素加入到结果向量ans中。
    7. 最后,返回结果向量ans作为最终的结果。

    复杂度

            时间复杂度:

                    O(n)

    时间复杂度为O(n),其中n表示数组nums的大小。因为每个元素最多进出队列一次,所以总共有2n次操作,因此时间复杂度为O(n)。

            空间复杂度

                    O(k)

    空间复杂度是O(k),其中k为窗口大小。因为单调队列中最多存储k个元素,所以空间复杂度为O(k)。值得注意的是,如果窗口大小为1,即每个元素都被作为一个窗口进行处理,那么空间复杂度将是O(n)。

    c++ 代码

     ​
    
    1. class Solution {
    2. public:
    3. class myqueue{
    4. public:
    5. deque<int>que; // 使用deque作为存储队列元素的容器
    6. void pop(int value) // 弹出value,如果当前队列的首元素等于value
    7. {
    8. if(!que.empty() && value == que.front()) // 如果队列不为空且队列首元素等于value
    9. que.pop_front(); // 弹出队列首元素
    10. }
    11. void push(int value) // 将value插入队列中
    12. {
    13. while(!que.empty() && value > que.back()) // 如果队列不为空且value大于队列末尾元素
    14. que.pop_back(); // 弹出队列末尾元素,以保持队列单调递减
    15. que.push_back(value); // 插入value到队列末尾
    16. }
    17. int front(){ // 返回队列的首元素
    18. return que.front();
    19. }
    20. };
    21. public:
    22. vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    23. myqueue que; // 创建一个myqueue对象
    24. vector<int> ans; // 存储结果的向量
    25. for(int i = 0; i < k; i++) // 初始化窗口的大小,将前k个元素插入队列中
    26. {
    27. que.push(nums[i]);
    28. }
    29. ans.push_back(que.front()); // 将队列的首元素(当前窗口的最大值)加入结果向量中
    30. for(int i = k; i < nums.size(); i++) // 从第k个元素开始遍历数组
    31. {
    32. que.pop(nums[i - k]); // 弹出窗口外的元素
    33. que.push(nums[i]); // 将当前元素插入队列中
    34. ans.push_back(que.front()); // 将队列的首元素加入结果向量中
    35. }
    36. return ans; // 返回结果向量
    37. }
    38. };

    觉得有用的话可以点点赞,支持一下。

    如果愿意的话关注一下。会对你有更多的帮助。

    每天都会不定时更新哦  >人<  。

  • 相关阅读:
    算法题(java)
    微信小程序案例2-3:婚礼邀请函
    1143 汉诺塔
    《操作系统》期末客观题梳理
    Kubernetes - 一键安装部署 K8S(附:Kubernetes Dashboard)
    哈希表 | 有效字母异位词 | leecode刷题笔记
    小型气象站硬件和软件均采用模块组合式开放性设计,可灵活组合使用
    水星 Mercury MIPC251C-4 网络摄像头 ONVIF 与 PTZ 云台控制
    springBoot配置拦截器
    银行测试人员谈测试需求
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/133501095