【算法日记】力扣239 滑动窗口最大值

embedded/2024/10/21 0:22:33/

题目描述

给你一个整数数组 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       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  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

思路

首先,最好想的是暴力解决,但是暴力方法的时间复杂度是O(n * k),当n或者k增加,乘积将会非常大,非常容易TLE。不妨换一种方法,我们使用一个队列,这个队列比较特殊,在队首的是这个区间内的最大值,有了这个队列,这个题就会非常好解决,但是STL中没有这样的队列,我们只能手搓一下这个队列。手搓之前,我们先来构思一下:

  1. 这个类需要有队列的基本功能
  2. pop出来的时候,只有当参数等于队列前元素时弹出队列前元素
  3. push进去的时候,当参数大于队尾时,pop队尾所有元素,该元素push队列(保证队尾元素是即将最大的元素)
  4. front函数就很简单了,调用就告诉你这个区间的最大值

基于上面的美好愿景,我们使用deque来实现,也就是我们的这个队列是基于deque魔改

deque<int> que;

deque是一个双向队列

下面是这个类的源码:

class MyQueue {public:deque<int> que;// 函数说明:当参数等于队列前元素时弹出队列前元素void pop(int value) {if (!que.empty() && value == que.front()) {que.pop_front();}}// 函数说明:当参数大于队尾时,pop队尾所有元素,该元素push队列(保证队尾元素是即将最大的元素)void push(int value) {while (!que.empty() && value > que.back()) {que.pop_back();}que.push_back(value);}//  函数说明:获得当前窗口的最大元素int front() {return que.front();}
};

主函数源码:

public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> res;// 先放入前k个元素for (int i = 0; i < k; i++) {que.push(nums[i]);}res.push_back(que.front());for (int i = k; i < nums.size(); i++) {que.pop(nums[i-k]);que.push(nums[i]);res.push_back(que.front());}return res;}
};

口头来描述一下主函数的过程,我们说我们现在实现的函数是调用front函数就会告诉你窗口最大值那么怎么判断这个队首元素该弹出了呢,我们可以来滑动窗口,当窗口末尾的元素和这个队列的首项相同时弹出,那么队列的队首就会变为下一个元素,我们称这个元素是即将要变为最大的元素,那么这个元素怎么来的呢?也是通过滑动窗口时,进来的元素和队尾打擂台,比他大,队尾就走,赢家就进入,通过这样,我们就可以保持队尾的元素,也就是即将变大的元素总是最大的,名副其实

程序源码

class Solution {
private:class MyQueue {public:deque<int> que;// 函数说明:当参数等于队列前元素时弹出队列前元素void pop(int value) {if (!que.empty() && value == que.front()) {que.pop_front();}}// 函数说明:当参数大于队尾时,pop队尾所有元素,该元素push队列(保证队尾元素是即将最大的元素)void push(int value) {while (!que.empty() && value > que.back()) {que.pop_back();}que.push_back(value);}//  函数说明:获得当前窗口的最大元素int front() {return que.front();}};
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> res;// 先放入前k个元素for (int i = 0; i < k; i++) {que.push(nums[i]);}res.push_back(que.front());for (int i = k; i < nums.size(); i++) {que.pop(nums[i-k]);que.push(nums[i]);res.push_back(que.front());}return res;}
};

http://www.ppmy.cn/embedded/129133.html

相关文章

已解决:ModuleNotFoundError: No module named ‘pip‘

[已解决] ModuleNotFoundError: No module named ‘pip‘ 文章目录 写在前面问题描述报错原因分析 解决思路解决办法1. 手动安装或升级 pip2. 使用 get-pip.py 脚本3. 检查环境变量配置4. 重新安装 Python 并确保添加到 PATH5. 在虚拟环境中安装 pip6. 使用 conda 安装 pip&…

持续科技创新 高德亮相2024中国测绘地理信息科技年会

图为博览会期间, 自然资源部党组成员、副部长刘国洪前往高德企业展台参观。 10月15日&#xff0c;2024中国测绘地理信息科学技术年会暨中国测绘地理信息技术装备博览会在郑州召开。作为国内领先的地图厂商&#xff0c;高德地图凭借高精度高动态导航地图技术应用受邀参会。 本…

Windows电脑桌面如何弄个好用的提醒备忘录?

在这个充满挑战的时代&#xff0c;每个人都渴望成为更好的自己。然而&#xff0c;随着生活节奏的加快&#xff0c;我们时常发现自己陷入了各种琐事之中&#xff0c;难以脱身。为了不让重要的事情被遗漏&#xff0c;一款好的提醒备忘录工具就显得尤为关键。那么&#xff0c;Wind…

jmeter中用csv data set config做参数化2

在jmeter中&#xff0c;使用csv data set config进行参数化是很重要的一个功能&#xff0c;但是这个功能的使用需要十分仔细和小心&#xff0c;因为细节之处往往决定着结果的正确与否。 举例&#xff1a; 一个登录接口用加密密码登录&#xff0c;一个登录接口用原始密码登录。…

【前端】Bootstrap:快速开始

Bootstrap 是一个功能强大且易于使用的前端框架&#xff0c;专门用于创建响应式和移动优先的网页。学习Bootstrap不仅可以帮助你快速构建现代网页&#xff0c;还可以提升你对前端开发流程的理解。本教程将从基础概念开始&#xff0c;逐步引导你掌握Bootstrap&#xff0c;并通过…

HarmonyOS 鸿蒙面试第一弹

鸿蒙面试第一弹 答案持续更新中 1、自我介绍2、鸿蒙项目介绍3、你接触鸿蒙多久了4、项目给你&#xff0c;鸿蒙项目给你能独立完成吗&#xff1f;5、装饰器有哪些 Component&#xff1a;用于定义可重用的UI组件。 Entry&#xff1a;用于标识页面的入口组件。 Reusable&#x…

62天框架安全(学习)

发现学了之后没有去复习&#xff0c;每天都要问自己学了什么&#xff0c;复习了吗&#xff0c;下次还能记住吗 一下内容来自【小迪安全2023】第62天:服务攻防-框架安全&CVE复现&Spring&Struts&Laravel&ThinkPHP_小迪安全文档2023-CSDN博客 一个网站的源码…

Cesium 影像加载的TileReplacementQueue技术

本文以分析QuadtreePrimitive及相关影像内容&#xff0c;讨论一些流程和方法。影像和地形是Cesium的基础内容&#xff0c;但是有时候感觉这部分的加载和渲染效率并不高。 TileReplacementQueue是一个非常神奇的类&#xff0c;我自己研究了小半天。虽然结构简单&#xff0c;但是…