剑指 Offer 59 - I. 滑动窗口的最大值

news2024/11/15 20:04:22

摘要

剑指 Offer 59 - I. 滑动窗口的最大值

一、大顶堆求解

对于每个滑动窗口,我们可以使用 O(k) 的时间遍历其中的每一个元素,找出其中的最大值。对于长度为n的数组 nums而言,窗口的数量为 n−k+1,因此该算法的时间复杂度为 O((n−k+1)k)=O(nk),会超出时间限制,因此我们需要进行一些优化。

    public int[] maxSlidingWindow1(int[] nums, int k) {
        PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        int[] result=new int[nums.length-(k-1)];
        int x=0;
        // 将数据放置到queue中
        int index=0;
        while (index<nums.length){
            while (index<nums.length&&(queue.isEmpty()||queue.size()!=k)){
                queue.add(nums[index++]);
            }
            result[x++]=queue.peek();
            queue.remove(nums[index-k]);
        }
        return result;
    }

复杂度分析

时间复杂度:O(nlong(n)) ,n次遍历,log(n)每一次大顶堆的找到的最大值

空间复杂度:O(n) 存储结果数据量。

二、双端队列

我们可以想到,对于两个相邻(只差了一个位置)的滑动窗口,它们共用着 k−1个元素,而只有 1 个元素是变化的。我们可以根据这个特点进行优化。

窗口对应的数据结构为双端队列 ,本题使用单调队列即可解决以上问题。遍历数组时,每轮保证单调队列 deque:

  • deque 内 仅包含窗口内的元素⇒ 每轮窗口滑动移除了元素 nums[i−1] ,需将 deque内的对应元素一起删除。
  • deque内的元素非严格递减⇒ 每轮窗口滑动添加了元素 nums[j+1],需将 deque内所有 <nums[j+1]的元素删除。

算法流程:

  • 初始化:双端队列deque,结果列表res ,数组长度 n;
  • 滑动窗口: 左边界范围 i∈[1−k,n−k] ,右边界范围 j∈[0,n−1];
  •           若 i>0且队首元素deque[0]== 被删除元素 nums[i−1] :则队首元素出队;
  •           删除deque内所有<nums[j]的元素,以保持 deque递减;
  •           将 nums[j]添加至deque尾部;
  •           若已形成窗口(即 i≥0):将窗口最大值(即队首元素 deque[0])添加至列表 resres ;
  • 返回值: 返回结果列表res;

    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 j = 0, i = 1 - k; j < nums.length; i++, j++) {
            // 删除 deque 中对应的 nums[i-1]
            if (i > 0 && deque.peekFirst() == nums[i - 1]) {
                deque.removeFirst();
            }
            // 保持 deque 递减
            while (!deque.isEmpty() && deque.peekLast() < nums[j]) {
                deque.removeLast();
            }
            deque.addLast(nums[j]);
            // 记录窗口最大值
            if (i >= 0) {
                res[i] = deque.peekFirst();
            }
        }
        return res;
    }
public int[] maxSlidingWindow3(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;
    }

复杂度分析:

  • 时间复杂度 O(n) : 其中 n为数组nums 长度;线性遍历 nums占用 O(n) ;每个元素最多仅入队和出队一次,因此单调队列 deque占用 O(2n)。
  • 空间复杂度 O(k) : 双端队列 deque 中最多同时存储 k个元素(即窗口大小)。

博文参考

《leetcode》

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

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

相关文章

在线图片转gif怎么操作?试试这一招在线制作gif

静图怎么变成gif动图&#xff1f;想要将手中的静态图片变成gif动图又不想下载软件的时候要怎么操作呢&#xff1f;很简单&#xff0c;通过使用【GIF中文网】的动图在线制作&#xff08;https://www.gif.cn/&#xff09;功能&#xff0c;两招就能在线制作gif图片&#xff0c;方便…

小红书购物笔记在哪里看?

小红书购物笔记在哪里看&#xff1f;#小红书带货#小红书变现#小红书运营#小红书营销#内容营销 在现在这个时代&#xff0c;网上购物已经成为一种日常的行为。每天大量的人在通过小红书购买他们心仪的商品&#xff0c;生活态度也越来越追求高品质。小红书不但能够让用户在网上购…

Metasploit框架基础(二)

文章目录前言一、Meatsplooit的架构二、目录结构datadocumentationlibmodulesplugins三、Measploit模块四、Metasploit的使用前言 Metasploit是用ruby语言开发的&#xff0c;所以你打开软件目录&#xff0c;会发现很多.rb结尾的文件。ruby是一门OOP的语言。 一、Meatsplooit的…

【opencv源码解析0.1】opencv库VS环境配置

opencv环境配置 感谢大家学习这门教程。本系列文章首发于公众号【周旋机器视觉】。 这个这门课程的第一篇文章&#xff0c;主要是opencv环境配置。 本教程的环境为 Visual Studio 2019CMake 3.22.3opencv 4.6.0windows 10 1、opencv的源码下载与安装 直接访问opencv官网&…

MySQL数据库优化————COUNT优化

直接进入主题 索引对count语句的影响 在我们对departments表进行count查询时&#xff0c;使用了以下语句 select count(*) from employees;当前employees表索引情况如图 只有一个主键索引 执行 explain select count(*) from employees;从结果中可以看到&#xff0c;这时…

NOIP2014-提高组初赛C语言解析(选择填空题)

第二十届(2014年)全国青少年信息学奥林匹克联赛初赛一、单项选择题&#xff08;共 20 题&#xff0c;每题 1.5 分&#xff0c;共计 30 分。每题有且仅有一个正确选项&#xff09;1. 以下哪个是面向对象的高级语言&#xff08; B &#xff09;A.汇编语言 B.C C.Fortran D.Basic参…

【opencv源码解析0.4】如何使用cmake来管理项目

如何使用cmake来管理项目 【opencv源码解析0.1】VS如何优雅的配置opencv环境 【opencv源码解析0.2】如何编译opencv库源码 【opencv源码解析0.3】调试opencv源码以及使用cmake来管理项目 前面几篇文章我们都是围绕Visual Studio 2019这个IDE来展开的&#xff0c;IDE为我们做了…

矩阵中的路径-剑指Offer-java深度优先

一、题目描述给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相…

k8s部署mysql+初始化数据

1. 准备工作 1.k8s的前置内容需要提前了解 2.mysql的初始化数据 3.docerk相关知识点需要了解 2. 部署步骤 初始化数据文件准备&#xff0c;准备了nacos的一张表sql脚本&#xff0c;需要修改一点点内容 文件名称&#xff1a;init-nacos.sql 部分内容显示&#xff1a; 主要创建…

潘长江张杰再现狂飙名场面,一般人把握不住

潘长江张杰再现狂飙名场面&#xff0c;一般人把握不住#我们的客栈#高启强#老墨我饿了 在昨晚播出的《我们的客栈》在猜人游戏的环节中&#xff0c;张杰和潘长江商量了一番&#xff0c;决定还原《狂飙》某一名场面&#xff0c;没想到被张维伊一秒猜出&#xff0c;张维伊还说这是…

图像分类竞赛进阶技能:OpenAI-CLIP使用范例

OpenAI-CLIP 官方介绍 尽管深度学习已经彻底改变了计算机视觉&#xff0c;但目前的方法存在几个主要问题:典型的视觉数据集是劳动密集型的&#xff0c;创建成本高&#xff0c;同时只教授一组狭窄的视觉概念;标准视觉模型擅长于一项任务且仅擅长于一项任务&#xff0c;并且需要大…

【QT专栏】QT中实现多线程的四种方式总结(金针菇般细)

目录 一、继承QThread 1&#xff0c;基本概念 2&#xff0c;操作流程 二、继承QObject&#xff08;推荐&#xff09; 1&#xff0c;基本概念 2&#xff0c;操作流程 三、继承QRunnable&#xff0c;配合QThreadPool实现多线程 1&#xff0c;外界通信 2&#xff0c;QMet…

SpringSecurity的安全认证的详解说明(附完整代码)

SpringSecurity登录认证和请求过滤器以及安全配置详解说明 环境 系统环境&#xff1a;win10 Maven环境&#xff1a;apache-maven-3.8.6 JDK版本&#xff1a;1.8 SpringBoot版本&#xff1a;2.7.8 根据用户名密码登录 根据用户名和密码登录&#xff0c;登录成功后返回Token数据…

狂神聊Redis复习笔记一

目录目前一个基本的互联网项目&#xff01;NoSQL 特点Redis 是什么&#xff1f;Redis 能干嘛&#xff1f;特性测试性能基础的知识Redis 是单线程的&#xff01;Redis 为什么单线程还这么快&#xff1f;五大数据类型Redis-KeyString&#xff08;字符串&#xff09;List&#xff…

[软件工程导论(第六版)]第3章 需求分析(复习笔记)

文章目录3.1 需求分析的任务3.2 与用户沟通获取需求的方法3.3 分析建模与规格说明3.4 实体-联系图&#xff08;E-R图&#xff09;3.5 数据规范化3.6 状态转换图3.7 其他图形工具3.8 验证软件需求需求分析是软件定义时期的最后一个阶段&#xff0c;需求分析的基本任务是准确的回…

EASYui+C#web

第一步创建一个web应用程序。 选择web应用程序。 第二步选择mvc框架 创建完成项目目录。 如图引入easyui包。 记住复制到content文件夹&#xff0c;否则无法识别。 easyui下载&#xff0c;官网。 如何用 引入jscss文件 <link rel"stylesheet" type"text…

Guitar Pro8手机电脑免费版吉他软件下载

Guitar Pro8是专业的吉他软件&#xff0c;具有可视化的五线谱编辑器&#xff0c;涵盖常用的乐器和特殊乐器单元&#xff0c;内置海量吉他音色效果和1000多个乐器音色&#xff0c;成为一个小型音乐站&#xff0c;制作出动听的音乐&#xff0c;支持边看边听&#xff0c;添加音频轨…

【论文阅读】 Few-shot object detection via Feature Reweighting

Few-shot object detection的开山之作之一 ~~ 特征学习器使用来自具有足够样本的基本类的训练数据来 提取 可推广以检测新对象类的meta features。The reweighting module将新类别中的一些support examples转换为全局向量&#xff0c;该全局向量indicates meta features对于检…

使用MindSpore20.0的API快速实现深度学习模型之数据变换

文章目录前言一. 实验环境二. 安装ubuntu虚拟机2. 1.下载ubuntu镜像2.2 配置虚拟机2.3 安装操作系统三. 安装MindSpore20.0-alpha3.1 下载需要的安装程序脚本3.2 安装MindSpore 2.0.0-alpha和Python 3.73.3 开始手动安装3.4. 安装gcc3. 5.安装MindSpore3.6. 验证是否成功&#…

【opencv源码解析0.3】调试opencv源码的两种方式

调试opencv源码的两种方式 上两篇我们分别讲了如何配置opencv环境&#xff0c;以及如何编译opencv源码方便我们阅读。但我们还是无法调试我们的代码&#xff0c;无法以我们的程序作为入口来一步一步单点调试看opencv是如何执行的。 【opencv源码解析0.1】VS如何优雅的配置ope…