【LeetCode】剑指 Offer 59. 队列的最大值 p288 -- Java Version

news2024/11/27 2:44:30

1. 题目介绍(59. 队列的最大值)

面试题59:队列的最大值, 一共分为两小题:

  • 题目一:滑动窗口的最大值
  • 题目二:队列的最大值

2. 题目1:滑动窗口的最大值

题目链接:https://leetcode.cn/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/

2.1 题目介绍

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

【测试用例】:
在这里插入图片描述

【条件约束】:

提示

  • 你可以假设 k 总是有效的,在输入数组 不为空 的情况下,1 ≤ k ≤ nums.length

【相关题目】:

注意:本题与主站 239. 滑动窗口最大值 题目相同。

2.2 题解 – 单调队列 – O(n)

时间复杂度O(n),空间复杂度O(k)

解题思路】:
1. 蛮力法:扫描每个滑动窗口的所有数字并找出其中的最大值。

  • 如果滑动窗口的大小为 k,则需要 O(k) 时间才能找出滑动窗口里的最大值。
  • 对于长度为 n 的输入数组,这种算法的总时间复杂度是 O(nk)

……
2. 单调队列
在这里插入图片描述
我们可以通过 双端队列 来存储 可能成为滑动窗口最大值的元素,且要保证队首元素始终为 当前窗口的最大值:(主要有两步操作)

  1. 移除队首:即 队首元素已经从窗口滑出
  2. 移除队尾:即 队尾元素 小于 即将入队元素

……
将 “未形成窗口” 和 “形成窗口后” 两个阶段拆分到两个循环里实现,可以减少冗余的判断操作
……
实现策略】:

  1. 首先进行无效输入判断,判断入参是否正确;
  2. 创建双端队列 deque 与 返回数组 res
  3. 将数组元素依次入队,并根据条件进行相应的移除操作,整个过程被分为了两个阶段:未形成窗口 和 形成窗口后;
  4. 在窗口移动的过程中,通过 res 存储当前窗口的最大值,并最终返回。
class Solution {
    // Solution1:双端队列
    public int[] maxSlidingWindow(int[] nums, int k) {
        // 无效输入判断
        if (nums.length <= 0 || k <= 0) return new int[0];
        // 创建双端队列
        Deque<Integer> deque = new LinkedList<>();
        // 定义数组变量,存储滑动窗口最大值
        int[] res = new int[nums.length - k + 1];
        // 未形成滑动窗口
        for (int i = 0; i < k; i++) {
            // 如果 队尾元素 小于 当前数组元素,就移除队尾
            while (!deque.isEmpty() && deque.peekLast() < nums[i])
                deque.removeLast();
            deque.addLast(nums[i]);
        }
        // 形成窗口后
        res[0] = deque.peekFirst();
        for(int i = k; i < nums.length; i++) {
            // 开始滑动窗口,队首已经从窗口移出
            if(deque.peekFirst() == nums[i - k])
                deque.removeFirst();
            // 如果 队尾元素 小于 当前数组元素,则移除队尾
            while(!deque.isEmpty() && deque.peekLast() < nums[i])
                deque.removeLast();
            deque.addLast(nums[i]);
            // 每滑动一次,记录一次当前窗口的最大值
            res[i - k + 1] = deque.peekFirst();
        }
        return res;
    }
}

在这里插入图片描述

3. 题目2:队列的最大值

题目链接:https://leetcode.cn/problems/dui-lie-de-zui-da-zhi-lcof/

3.1 题目介绍

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数 max_valuepush_backpop_front 的均摊时间复杂度都是 O(1)

若队列为空,pop_frontmax_value 需要返回 -1

【测试用例】:
示例 1:

输入:
[“MaxQueue”,“push_back”,“push_back”,“max_value”,“pop_front”,“max_value”]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]

示例2:

输入:
[“MaxQueue”,“pop_front”,“max_value”]
[[],[],[]]
输出: [null,-1,-1]

【条件约束】:

限制

  • 1 <= push_back,pop_front,max_value的总操作数 <= 10000
  • 1 <= value <= 10^5

3.2 题解 – 双端队列 – O(1)

时间复杂度O(1),空间复杂度O(n)

解题思路】:
1. 暴力求解:直接实现一个普通的队列,查询最大值时遍历计算;
2. 单调队列:该题解与上一题 滑动窗口的最大值类似,具体过程可以参考上一题。

class MaxQueue {
    // 定义队列
    // queue 负责作为一个正常的队列结构
    // deque 用来存储当前队列的最大值
    Queue<Integer> queue;
    Deque<Integer> deque;

    // 初始化队列
    public MaxQueue() {
        queue = new LinkedList<>();
        deque = new LinkedList<>();
    }
    
    // 返回deque中的队首元素
    public int max_value() {
        return deque.isEmpty() ? -1 : deque.peekFirst();
    }
    
    // 从队尾方向入队
    public void push_back(int value) {
        // queue直接入队
        queue.offer(value);
        // deque需要判断一下该元素是否大于队尾元素,如果是则移除队尾
        while (!deque.isEmpty() && deque.peekLast() < value)
            deque.removeLast();
        deque.offerLast(value);
    }
    
    // 从队首方向出队
    public int pop_front() {
        // 判断当前是否队空
        if(queue.isEmpty()) return -1;
        // deque出不出队,取决于当前要出队的元素是不是最大值
        if (queue.peek().equals(deque.peekFirst())) deque.removeFirst();
        return queue.poll();
    }
}

/**
 * Your MaxQueue object will be instantiated and called as such:
 * MaxQueue obj = new MaxQueue();
 * int param_1 = obj.max_value();
 * obj.push_back(value);
 * int param_3 = obj.pop_front();
 */

在这里插入图片描述

4. 参考资料

[1] 剑指 Offer 59 - I. 滑动窗口的最大值(单调队列,清晰图解)
[2] 剑指 Offer 59 - II. 队列的最大值(单调双向队列,清晰图解)

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

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

相关文章

3.rabbitmq-集群

1.修改3台的主机名称,也可以不改 vi /etc/hostname 2.配置各个节点的host文件,让各节点都能识别对方 vi /etc/hosts 192.168.3.132 host-rabbitmq 192.168.3.133 host-rabbitmq2 192.168.3.134 host-rabbitmq3 3.以确保各个节点的cookie文件使用的同一个值 在node1上执行远程命…

基于矩阵分解的推荐算法

1.背景 推荐系统的两大应用场景分别是评分预测(Rating Prediction)和Top-N推荐(Item Ranking)。其中评分预测主要用于评价网站&#xff0c;比如用户给自己看过的电影评多少分&#xff0c;或者用户给自己看过的书籍评价多少分&#xff0c;矩阵分解技术主要应用于评分预测问题&am…

买车了

最近先后去试驾了比小鹏P7i、蔚来ET5、智己LS7、亚迪汉这几辆车&#xff0c;这四个品牌总共花了三天时间&#xff0c;也算是比较深度的试驾吧&#xff0c;静态和动态、前后排、主副驾都感受了一下。前面写了比亚迪汉的试驾体验&#xff0c;详细分析了它的优缺点&#xff1a;不愧…

Vue过滤器、自定义指令、组件

目录 一&#xff1a;生命周期 1.1 生命周期实例 1.2 生命周期函数&#xff08;引入&#xff09; 二&#xff1a;过滤器 三&#xff1a;自定义指令 四&#xff1a;组件 4.1 非单文件组件 4.2 组件的嵌套 4.3 单文件组件 模板 4.3.1 架构 4.3.2 不同版本的vue.JS 4…

ASRT语音识别系统部署及模型训练笔记

ASRT语音识别系统部署及模型训练笔记 前言 ASRT是一个中文语音识别系统&#xff0c;由AI柠檬博主开源在GitHub上。 GitHub地址&#xff1a;nl8590687/ASRT_SpeechRecognition 国内Gitee镜像地址&#xff1a;AI柠檬/ASRT_SpeechRecognition 文档地址&#xff1a;ASRT语音识…

ping telnet curl的使用方法和应用场景

文章目录一、区别二、使用方法pingtelnetcurl三、应用场景一、区别 ping命令基于ICMP协议&#xff0c;通过发送发送ICMP数据包&#xff0c;并查看对方是否有返回数据来检测网络是否连通&#xff0c;仅包含控制信息&#xff0c;不包含端口号; telnet是对服务器的远程登录&#…

全网火爆,Python接口自动化测试,从0到1分层封装框架撸码(带接口)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 随着行业内卷越来越…

3D开发工具HOOPS最新解析合集,助力实现web端高性能模型渲染

一、3D技术为创新提供强大助力 不管您想搭建桌面、WEB或者移动端APP应用&#xff0c;技术领先全球的HOOPS Platform组件都可以为您提供弹性的3D集成架构&#xff0c;同时&#xff0c;一批可信任的工业领域3D技术专家也将为您提供技术支持服务。 如果您的客户期望有一种在多个…

Docker 配置远程访问

Docker客户端通常通过Unix套接字在本地与守护程序通信 /var/run/docker.sock&#xff0c;或通过网络通过TCP套接字。 以下是启动时提供给Docker守护程序的选项的典型示例&#xff1a; # ps -ef |grep dockerd root 23438 1 0 00:41 ? 00:00:03 /usr/bin/dock…

Spring入门案例--IOC入门案例

IOC入门案例思路分析 (1)Spring是使用容器来管理bean对象的&#xff0c;那么管什么? 主要管理项目中所使用到的类对象&#xff0c;比如(Service和Dao) (2)如何将被管理的对象告知IOC容器? 使用配置文件 (3)被管理的对象交给IOC容器&#xff0c;要想从容器中获取对象&…

TCP协议详解

1.TCP的准备条件在古代的时候&#xff0c;古人们经常写书信进行交流&#xff0c;写书信的前提是你要知道这份信是要寄给谁在网络中&#xff0c;我们通过ip端口号找对目标对象&#xff0c;但是现在网站一般会对ip端口注册一个域名&#xff0c;所以我们一般就是对域名进行查找&am…

minikube安装与运行(阿里云环境运行)

说下为啥选择云环境&#xff0c;最开始在本地电脑上安装的minikube&#xff0c;但是由于国内的网络访问不了谷歌的镜像仓库&#xff0c;安装ingress-nginx或者其他插件时着实的恶心。要不翻墙&#xff0c;要不自己搭建个镜像仓库。最终决定用阿里云境外的节点&#xff0c;按小时…

Windows操作系统C盘快速扩容工具推荐

Windows 系统C 盘扩容教程 1️⃣前言 大家在使用电脑过程中&#xff0c;随着时间的推移&#xff0c;经常会发现C盘空间爆红的情况&#xff0c;主 要原因是电脑软件在使用过程中产生的缓存文件或者日志文件大部分都会存储在C盘&#xff0c;这样时间一久&#xff0c;C盘的存储空…

不联网新华字典

介绍 首页字典 更多 包含内容 内容对应Json数据文件百家姓baijiaxing.json曹操诗集caocao.json弟子规dizigui.json成语idiom.json论语lunyu.json纳兰性德诗集nalanshiji.json千家诗qianjiashi.json千字文qianziwen.json三字经-传统版sanzijing_ct.json三字经-新版sanzijing_x…

「STM32入门」TIM定时中断

定时器的简介 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断&#xff0c;在中断内可以执行中断事件不仅具备基本的定时中断功能&#xff0c;而且还包含内外时钟源选择&#xff0c;主从触发模式&#xff0c;输入捕获&#xff0c;输出捕获&#xff…

MySQL调优笔记——慢SQL优化记录

上周&#xff0c;项目出现线上问题&#xff0c;在这家公司做的是一个SAAS平台&#xff0c;总用户量大约10万人&#xff1b; 经过排查&#xff0c;发现是SQL问题&#xff0c;导致数据库响应慢&#xff0c;进而拖垮了整体服务&#xff1b; 通常&#xff0c;查询耗时较长的SQL涉…

我在windows10下,使用CMake gui 编译krita源码,CMake gui报错:LibMyPaint_DIR-NOTFOUND

系列文章目录 文章目录系列文章目录前言一、原因二、解决1.引入库前言 我在windows10下&#xff0c;使用CMake gui 编译krita源码 where is the source code:E:/krita-dev/krita where to build the binaries:E:/krita-dev/krita_camke current generator:MinGW Makefiles 分别…

ios证书申请流程

mac电脑-钥匙串-请求证书-得到CertificateSigningRequest 2.创建Identifiers &#xff08;1&#xff09; (2) (3) (4) 如要接推送等 勾&#xff1a;Push Notifications 如要生成universal links 勾&#xff1a;Associated Domains 3.创建Certificates 注意&#xff1a;需…

银行数字化转型导师坚鹏:《银行保险监管统计管理办法》

《银行保险监管统计管理办法》 ——“监”听则明 护航银行高质量发展课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不清楚《银行保险监管统计管理办法》出台背景&#xff1f; 不知道如何理解《银行保险监管统计管理办法》相关规定&#xff1f; 不清楚如何落…

UI设计师都在用这5个网站,赶紧马住~

本期推荐5个UI设计师常用的素材、学习网站&#xff0c;设计师们赶紧收藏~ 1、菜鸟图库 https://www.sucai999.com/searchlist/UIsheji----all-0-0.html?vNTYxMjky 菜鸟图库提供了超多免费设计素材&#xff0c;在这里你可以找到平面、UI、电商等设计类素材&#xff0c;还有大…