滑动窗口最大值(力扣239题)

news2024/11/15 10:11:59
单调递减队列:

在解决题目之前,我们先来了解一下单调递减队列,它其实就是在队列的基础上多加了一些限制,如下图:

          要求队列中的元素必须按从大到小的顺序排列

如果向单调递减队列中加入数字 1,可以直接加入,不会改变队列中递减的要求。

但是向队列中加入数字 3 就不能直接加入了。需要把队列中的 2,1 移除,然后再加入 3。  

我们可以利用java中自带的LinkedList双端队列来实现一下单调递减队列。

import java.util.LinkedList;

//单调递减队列
public class MonotonicQueue<T extends Comparable<T>> {

    private final LinkedList<T> queue = new LinkedList<>();

    public T peek(){
        return queue.peekFirst();
    }

    public void poll(){
        queue.pollFirst();
    }

    public void offer(T t){
        while(!queue.isEmpty() && queue.peekLast().compareTo(t) < 0){
            queue.pollLast();
        }
        queue.offerLast(t);
    }

    @Override
    public String toString() {
        return queue.toString();
    }

    public static void main(String[] args) {
        MonotonicQueue<Integer> q = new MonotonicQueue<>();
        for(int i : new int[]{1, 3, -1, -3, 5, 3, 6, 7}){
            q.offer(i);
            System.out.println(q);
        }
    }
}

接下来我们用单调递减队列来解决力扣的一道题目

例题:

分析:

题目说了,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。假设滑动窗口的大小 k = 3,每次窗口右移,找出滑动窗口里的最大值并把它填入一个新数组中(滑动窗口必须被填满


我们可以使用单调递减队列来找到滑动窗口中的最大值,每次向单调递减队列加入元素,队列的队头元素就是滑动窗口里面的最大值。如下图(从左往右看)。

注意:只有当滑动窗口被填满时,才获取窗口里面的最大值。

有一种情况需要注意,如下图:

当队列中的元素超过滑动窗口的范围( k ),要及时把队头元素移除。

这里可以利用索引,当遍历到第 i 个索引时,i - k 处的元素就是过期的元素,应该移除。

也就是满足了 nums[i - k] == queue.peek() ,则移除队头元素。

注意:这里不能用队列大小当判断条件,当队列长度大于窗口大小(k)就移除元素,这样做可能会出问题。

如果把上图中的数字 -4 改为 1,当往队列加入1时,会把前面的-1,-3覆盖掉,此时队列长度小于滑动窗口值,用单调递减队列找到的最大值(数字3) 其实是过期的。

显然,此时滑动窗口的最大值为1。

代码实现:
package leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SlidingWindowMaxnum {

    public static int[] maxSlidingWindow(int[] nums, int k) {
        //创建单调递减队列
        MonotonicQueue<Integer> queue = new MonotonicQueue<>();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            //检查队列头部元素,超过滑动窗口范围要移除
            if(i >= k && nums[i - k] == queue.peek()){
                queue.poll();
            }
            int num = nums[i];
            queue.offer(num);
            if(i >= k - 1){
                list.add(queue.peek());
            }
        }
        return list.stream().mapToInt(Integer::intValue).toArray();
    }


    public static void main(String[] args) {
        System.out.println(Arrays.toString(maxSlidingWindow(new int[]{1, 3, -1, -3, 5, 3, 6, 7}, 3))); //[3, 3, 5, 5, 6, 7]
        //System.out.println(Arrays.toString(maxSlidingWindow(new int[]{7, 2, 4}, 2))); // [7, 4]
        //System.out.println(Arrays.toString(maxSlidingWindow(new int[]{1, 3, 1, 2, 0, 5}, 3))); // [3, 3, 2, 5]
        //System.out.println(Arrays.toString(maxSlidingWindow(new int[]{-7, -8, 7, 5, 7, 1, 6, 0}, 4))); // [7, 7, 7, 7, 7]
    }
}

可以把上面的集合换成数组,做一个小小的优化,放到力扣上跑会更好。

public static int[] maxSlidingWindow(int[] nums, int k) {
        MonotonicQueue<Integer> q = new MonotonicQueue<>();
        int[] output = new int[nums.length - (k - 1)];
        for (int i = 0; i < nums.length; i++) {
            if (i >= k && nums[i - k] == q.peek()) {
                q.poll();
            }
            int num = nums[i];
            q.offer(num);
            if (i >= k - 1) {
                output[i - (k - 1)] = q.peek();
            }
        }
        return output;
    }

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

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

相关文章

基于ElementUI封装的下拉树选择可搜索单选多选清空功能

效果&#xff1a; 组件代码 /*** 树形下拉选择组件&#xff0c;下拉框展示树形结构&#xff0c;提供选择某节点功能&#xff0c;方便其他模块调用* author wy* date 2024-01-03 * 调用示例&#xff1a;* <tree-select * :height"400" // 下拉框中树形高度* …

智慧工厂:科技与制造融合创新之路

随着科技的迅猛发展&#xff0c;智慧工厂成为制造业领域的热门话题。智慧工厂利用先进的技术和智能化系统&#xff0c;以提高生产效率、降低成本、增强产品质量和灵活性为目标&#xff0c;正在引领着未来制造业的发展。 智慧工厂的核心是数字化和自动化生产&#xff0c;相较于传…

C语言实例_string.h库函数功能及其用法详解

一、前言 在计算机编程中&#xff0c;字符串处理是一项常见而重要的任务。C语言的string.h头文件提供了一系列函数和工具&#xff0c;用于对字符串进行操作和处理。这些函数包括字符串复制、连接、比较、查找等功能&#xff0c;为开发人员提供了强大的字符串处理能力。本文将对…

vue3中pdf打印问题处理

1 get请求参数问题 之前的请求是post得不到参数&#xff0c;今天发现的问题很奇怪&#xff0c;从前端进入网关&#xff0c;网关居然得不到参数。 前端代码 const print () > {let linkUrlStr proxy.$tool.getUrlStr(proxy.$api.invOrder.psiInvOrder.printSalOutstock,{a…

Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中

场景 SpringBootVue整合WebSocket实现前后端消息推送&#xff1a; SpringBootVue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客 上面实现ws推送数据流程后&#xff0c;需要在windows上使用ws客户端定时记录收到的数据到文件中&#x…

鸿蒙开发学习——基本组件

文章目录 引言正文Image组件设置加载网络图片图片属性设置 Text组件设置文本显示内容text属性设置 TextInput输入文本TextInput Controller获取输入文本 Button按钮 引言 最近在学习鸿蒙系统开发&#xff0c;然后对着文档看还是有很多问题&#xff0c;这里结合官方给的demo进行…

在ARMv8中aarch64与aarch32切换

需求描述 在项目调试过程中,由于内存或磁盘空间不足需要将系统从aarch64切换到aarch32的运行状态去执行,接下来记录cortexA53的调试过程。 相关寄存器描述 ARM64: SPSR_EL3 N (Negative):表示运算结果的最高位,用于指示运算结果是否为负数。 Z (Zero):表示运算结果是否…

设计模式之建造者模式【创造者模式】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某…

c++语言基础17-判断集合成员

题目描述 请你编写一个程序&#xff0c;判断给定的整数 n 是否存在于给定的集合中。 输入描述 有多组测试数据&#xff0c;第一行有一个整数 k&#xff0c;代表有 k 组测试数据。 每组数据第一行首先是一个正整数 m&#xff0c;表示集合中元素的数量&#xff08;1 < m &…

程序媛的mac修炼手册--MacOS系统更新升级史

啊&#xff0c;我这个口罩三年从未感染过新冠的天选免疫王&#xff0c;却被支原体击倒&#x1f637;大意了&#xff0c;前几天去医院体检&#xff0c;刚检查完出医院就摘口罩了&#x1f926;大伙儿还是要注意戴口罩&#xff0c;保重身体啊&#xff01;身体欠恙&#xff0c;就闲…

微软截图工具SnippingTool_6.1.7601免费版

SnippingTool是一款win7系统自带的一款非常实用型截图工具&#xff0c;操作简单&#xff0c;点击“新建"可一键截图&#xff0c;截图之后会弹出编辑器&#xff0c;可以进行一些简单的勾画编辑操作&#xff0c;您可以使用笔、荧光笔、电子邮件或保存等选项。如果您的系统丢…

Liunx(CentOS)安装Nacos(单机启动,绑定Mysql)

Liunx安装Nacos(单机启动&#xff0c;绑定Mysql) 一&#xff0c;准备安装包 github下载点 二&#xff0c;在/usr/local/目录下创建一个文件夹用于上传和解压Nacos cd /usr/local/ #这里创建文件夹名字可随意&#xff0c;解压后会生成一个名为nacos的文件夹&#xff0c;后续…

全国计算机等级考试| 二级Python | 真题及解析(6)

全国计算机等级考试二级Python真题及解析(8)图文 一、选择题 1.python中表达式4**3=( )。 A.12 B.1 C.64 D.7 2.在Python中,通过( )函数查看字符的编码。 …

安全防御之授权和访问控制技术

授权和访问控制技术是安全防御中的重要组成部分&#xff0c;主要用于管理和限制对系统资源&#xff08;如数据、应用程序等&#xff09;的访问。授权控制用户可访问和操作的系统资源&#xff0c;而访问控制技术则负责在授权的基础上&#xff0c;确保只有经过授权的用户才能访问…

jQuery框架

1.1、jQuery简介 jQuery 是一个高效、精简并且功能丰富的 JavaScript 工具库。它提供的 API 易于使用且兼容众多浏览器&#xff0c;这让诸如 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作更加简单。目前超过90%的网站都使用了jQuery库&#xff0c;jQuery的宗旨&#xff1…

ElecardStreamEye使用教程(视频质量分析工具、视频分析)

文章目录 Elecard StreamEye 使用教程安装与设置下载安装 界面导航主菜单视频窗口分析窗口 文件操作打开视频文件 视频流分析帧类型识别码率分析分析报告 高级功能视觉表示比较模式自动化脚本 下载地址1&#xff1a;https://www.onlinedown.net/soft/58792.htm 下载地址2&…

计算机系统基础

C 语言相关内容省略&#xff0c;复习自用&#xff0c;仅供参考~ 概述 冯诺伊曼结构 存储程序工作方式&#xff1a;将事先编好的程序和原始数据送入主存后才能执行程序&#xff0c;程序被启动执行后&#xff0c;计算机能在不需要操作人员干预下自动完成逐条指令取出和执行的任…

【电商项目实战】实现订单超时支付取消

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

OpenHarmony源码转换器—多线程特性转换

本文讨论了如何将多线程的 Java 代码转换为 OpenHarmony ArkTS 代码​ 一、简介 Java 内存共享模型 以下示例伪代码和示意图展示了如何使用内存共享模型解决生产者消费者问题。 生产者消费者与共享内存间交互示意图 为了避免不同生产者或消费者同时访问一块共享内存的容器时…

阶段十-分布式-Redis02

第一章 Redis 事务 1.1 节 数据库事务复习 数据库事务的四大特性 A&#xff1a;Atomic &#xff0c;原子性&#xff0c;将所以SQL作为原子工作单元执行&#xff0c;要么全部执行&#xff0c;要么全部不执行&#xff1b;C&#xff1a;Consistent&#xff0c;一致性&#xff0…