Leetcode:239. 滑动窗口最大值(C++)

news2024/12/27 15:53: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       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]

实现代码和解析:

暴力法(会超时):

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) 
    {
        vector<int> result;
        //移动
        for(int i=0;i<nums.size()-k+1;i++)
        {
            int max=INT_MIN;
            for(int j=i;j<i+k;j++)
            {
                if(nums[j]>max)
                {
                    max=nums[j];
                }
            }
            result.push_back(max);//放入结果数组中
        }
        return result;
    }
};

原理思路:

        注意此方法会超时,就是直接暴力循环把每个窗口的最大值都遍历比较出来。

单调队列法:

//实现单调队列
class Myque
{
public:
    deque<int> que;//deque来实现单调队列
    //入单调队列
    void push(int n)
    {
        //将队列中比要入队列的元素小的全部弹出
        while(!que.empty()&&que.back()<n)
        {
            que.pop_back();
        }
        que.push_back(n);
    }
    //出单调队列
    void pop(int n)
    {
        //若本来该出队列的元素未在其他元素入队列的时候弹出,则将它出队列
        if(!que.empty()&&que.front()==n)
        {
            que.pop_front();
        }
    }
    //获得最大值
    int front()
    {
        return que.front();
        
    }
};
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) 
    {
        
        Myque que;
        vector<int> result;//接收结果
        //先将前k个数入单调队列
        for(int i=0;i<k;i++)
        {
            que.push(nums[i]);
        }
        result.push_back(que.front());//记录前k个的最大值
        //i指向右窗口端开始移动
        for(int i=k;i<nums.size();i++)
        {
            que.pop(nums[i-k]);//将出窗口的元素出队列
            que.push(nums[i]);//将进入窗口的元素入队列
            result.push_back(que.front());//记录当前窗口最大值
        }
        return result;
        
    }
};

原理思路:

        利用单调队列的经典题。下面就介绍一下单调队列。

单调队列:

        单调队列就是利用改变入队列和出队列的规则,使队列单调递增或递减,这里就是让最大值永远在队头(单调队列的实现不是固定的,需要根据具体的题)。

        首先要知道什么是deque,也是是双端队列,就是两端都可以入队列和出队列的一种结构。然后讲讲具体实现,我们用双端队列来实现单调队列,改变其出队列和入队列的规则。

        入队列:将队列中后面小于入队列元素的全部出队列,注意这里用的是while删除多个,而且是小于的,不能把等于的也出队列,因为我们在出队列时会判断出窗口元素是否会与队列头元素相同,如果把等于的也出队列,在某些情况下,会在出队列时移出本应该留在队列的元素,

    //入单调队列
    void push(int n)
    {
        //将队列中比要入队列的元素小的全部弹出
        while(!que.empty()&&que.back()<n)
        {
            que.pop_back();
        }
        que.push_back(n);
    }

        出队列:将出滑动窗口的元素移出队列,要判断一下移出元素与队头元素是否相等,若相等才出队列,因为不相等的话,说明此元素已经在我们入队列的时候移出队列了。

    //出单调队列
    void pop(int n)
    {
        //若本来该出队列的元素未在其他元素入队列的时候弹出,则将它出队列
        if(!que.empty()&&que.front()==n)
        {
            que.pop_front();
        }
    }

        获取最大值:其实就是返回队列头元素,因为我们实现了单调队列嘛。

    //获得最大值
    int front()
    {
        return que.front();
        
    }

        具体解题:我们先将前k个元素入队列,然后找出最大值记录在result数组中,然后我们开始移动窗口,在移动时入队列,出队列,记录每个窗口的最大值,这样我们就得到了结果。

        //先将前k个数入单调队列
        for(int i=0;i<k;i++)
        {
            que.push(nums[i]);
        }
        result.push_back(que.front());//记录前k个的最大值
        //i指向右窗口端开始移动
        for(int i=k;i<nums.size();i++)
        {
            que.pop(nums[i-k]);//将出窗口的元素出队列
            que.push(nums[i]);//将进入窗口的元素入队列
            result.push_back(que.front());//记录当前窗口最大值
        }

模拟过程:   

        看完如果还是不太明白为什么这样就能实现获取每个窗口的最大值,那我给出一个例子模拟一下过程,大家就能明白了,下面给出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础知识(二)

目录 顺序语句 条件语句 条件语句书写格式一及对比&#xff1a;if条件语句 条件语句书写格式二及对比&#xff1a;if...else...语句 条件语句书写格式三及对比&#xff1a;if...elif...else语句 空语句pass 条件语句的总结&#xff1a; 循环语句 while循环 与c/java/…

对于Muduo主从Reactor模式的理解

从12月20号开始看Muduo网络库&#xff0c;到28号的时候弄懂了EventLoop, Poller, Channel是怎么一回事&#xff0c;一番琢磨之后觉得还是应该发到博客上跟大家分享&#xff0c;特此记录。 对照linyacool那个webserver的实现&#xff0c;再看了一遍muduo的EventLoop, Poller ,C…

IDEA快速启动多个微服务模块 -idea如何开启Run DashBoard

文章目录 缘起 Run DashBoard面板如何开启开启 Run DashBoard 注意&#xff1a; 缘起 在idea里面如果需要启动多个项目的话&#xff0c;尤其是是比如微服务项目&#xff0c;动辄要启动五六个七八个应用&#xff0c;如果通过右上角那边启动会很不方便&#xff0c;你需要选择…

基于GIS简单处理世界土壤数据库(HWSD)的中国土壤数据集

来源&#xff1a;GIS前沿 一、 数据介绍 土壤属性表主要字段包括&#xff08;图1&#xff09;&#xff1a;详细描述请参考Harmonized World Soil Database (version 1.1).pdf文件&#xff0c;其中以T开头的土壤属性表示土壤上层的属性&#xff08;0-30cm&#xff09;&#xff…

【曲线全局逼近】

曲线全局逼近 本文是基于 这篇文章 翻译而来的&#xff0c;仅学习。 在插值中&#xff0c;插值曲线以给定的顺序通过所有给定的数据点。正如在全局插值页面中所讨论的&#xff0c;插值曲线可能会在所有数据点上摆动&#xff0c;而不是紧紧跟随数据多边形。为了克服这个问题&…

包装类的使用

文章目录一、单元测试方法的使用步骤二、包装类的使用基本数据类型、包装类、String类型之间的相互转化基本数据类型——>包装类注意包装类——>基本数据类型自动装箱与自动拆箱&#xff08;jdk5.0后&#xff09;基本数据类型、包装类——>String类型String类型——&g…

史上最全 Appium 自动化测试从基础到框架实战精华学习笔记(一)

1080402 31.8 KB 对测试人来说&#xff0c;Appium 是非常重要的一个开源跨平台自动化测试工具&#xff0c;它允许测试人员在不同的平台&#xff08;iOS、Android 等&#xff09;使用同一套 API 来写自动化测试脚本&#xff0c;这样可大幅提升代码复用率和工作效率。 本文汇总了…

郭盛华:警惕家庭智能扬声器中潜在的窃听风险

一名安全研究人员因识别Google Home智能扬声器中的安全问题而获得了107500美元的漏洞赏金&#xff0c;这些问题可能被用来安装后门并将其变成窃听设备。 国际知名网络黑客安全专家、东方联盟创始人郭盛华在一篇技术文章中透露&#xff1a;这些漏洞“允许无线附近的攻击者在设备…

服务的雪崩以及解决方案

文章目录一、什么是服务的雪崩二、服务雪崩形成的原因三、雪崩解决方案3.1 设置超时时间3.2 线程隔离&#xff08;舱壁模式&#xff09;3.3 熔断器&#xff08;断路器&#xff09;3.4 限流四、总结一、什么是服务的雪崩 服务的雪崩效应是一种因服务提供者不可用导致服务调用者…

从源码角度带你清楚分析Spring 的Lazy-init 延迟加载机制原理

lazy-init 延迟加载应用 ApplicationContext 容器的默认值行为是在启动服务器时将所有Singleton Bean 提前进行实例,提前实例化意味着作为初始化过程的一部分,ApplicationContext 实例会创建并配置所有的singleton Bean. 例如: <bean id"testBean" class"c…

张力控制PID增益(Kp)自适应算法详解(含SCL和梯形图完整源代码)

有关收放卷张力控制的详细内容,请参看下面的文章链接,这里不再赘述。 变频器简单张力控制(线缆收放卷应用)_RXXW_Dor的博客-CSDN博客张力控制的开闭环算法,可以查看专栏的其它文章,链接地址如下:PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-CSDN博客。https://blo…

ThinkPHP3.2.3_SQLi

文章目录ThinkPHP3.2.3_SQLi0x00 测试代码0x02 paylaod0x03 调用分析0x04 漏洞成因0x05 总结ThinkPHP3.2.3_SQLi 刚好有朋友在测一个目标是tp3.2.3框架的站遇到了一些问题 顺手跟一下流程复现一下吧。 0x00 测试代码 <?php namespace Home\Controller; use Think\Contr…

启岁新程|跨越2022,2023一起追光而行!

和气渐入东风&#xff0c;岁杪将迎春临&#xff0c; 时间的车轮即将驶离2022开往2023&#xff0c; 回首来时路&#xff0c;我们收获满满&#xff0c; 展望新征程&#xff0c;我们斗志昂扬...... 2022注定是不平凡的一年&#xff0c; 在这一年里&#xff0c; 我们与行业同行…

深度学习:07 CNN经典模型总结(LeNet-5、AlexNet、VGG、GoogLeNet、ResNet)

目录 CNN经典网络模型 LeNet-5 AlexNet VGG GoogLeNet (Inception) ResNet 如何选择网络 CNN经典网络模型 以下介绍了LeNet-5、AlexNet、VGG、GoogLeNet、ResNet等&#xff0c;它们通常用于图像的数据处理&#xff0c;那么卷积神经网络是否应用于自然语言分类任务呢&am…

.net可视化表单设计工具

在很多软件系统中&#xff0c;表单开发都是很重要的一个部分。在表单开发中&#xff0c;往往会遇到重复开发的问题&#xff0c;例如在页面搭建系统中&#xff0c;除了组件本身的逻辑&#xff0c;配置组件数据的表单通常也需要开发人员重复手动开发。这就导致开发人员不仅要维护…

VS1053音频解码器介绍

VS1053音频解码器简介 VS1053b是单片Ogg Vorbis/MP3/AAC/WMA/MIDI音频解码器&#xff0c;及IMA ADPCM 编码器和用户加载的Ogg Vorbis编码器。它包含了一个高性能、有专利的低功耗DSP处理器内核VS_DSP、工作数据存储器、供用户应用程序和任何固化解码器一起运行的16 KiB 指令RAM…

小程序:后台交互-首页

目录 一&#xff0c;数据库准备 二&#xff0c;后台准备 pom.xml 配置数据源 mybatis-generator 整合mybatis 三&#xff0c;准备前端首页的数据 Promise 封装request 会议展示 四&#xff0c;通过wxs将首页动态数据优化 一&#xff0c;数据库准备 二&#xff0c;后…

docker的镜像存放地址

今天突然想到一个问题&#xff0c;docker的镜像到底存在哪的&#xff0c;一直没太注意&#xff0c;稍微记录下 1、先查看下本地有哪些images docker images 2、找到docker的数据目录 /var/lib/docker 可以看到有好多的目录 盲猜一波大概也能猜到 containers 是当前运行的容器…

React-Router6路由相关一(路由的基本使用、重定向、NavLink·、路由表、嵌套路由)(七)

系列文章目录 第一章&#xff1a;React基础知识&#xff08;React基本使用、JSX语法、React模块化与组件化&#xff09;&#xff08;一&#xff09; 第二章&#xff1a;React基础知识&#xff08;组件实例三大核心属性state、props、refs&#xff09;&#xff08;二&#xff0…

Android OpenGL ES 学习(十二) - MediaCodec + OpenGL 解析H264视频+滤镜

OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用…