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

单调递减队列:

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

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

如果向单调递减队列中加入数字 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);}@Overridepublic 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.hqwc.cn/news/319016.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# Onnx yolov8 竹签计数、一次性筷子计数

目录 效果 模型信息 项目 代码 数据集 下载 C# Onnx yolov8 竹签计数、一次性筷子计数 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-01-03T08:55:22.768617 author&#xff1a;Ultralytics task&#xff1a;detect license&#x…

electron预加载脚本

webPreferences 指定预加载脚本,可以使用部分node脚本 webPreferences: {preload: path.join(__dirname, "preload.js"),},创建preload.js 中 测试文件读取功能 const fs require(fs) const text fs.readFileSync(package.json, utf-8)console.log(text)报错,为了…

单向可控硅电路图总结(2)

单向可控硅最筒单电路图&#xff08;一&#xff09; 触摸一下金属片开&#xff0c;SCR1导通&#xff0c;负载得电工作。触摸一下金属片关&#xff0c;SCR2导通&#xff0c;继电器J得电工作&#xff0c;K断开&#xff0c;负载失电&#xff0c;SCR2关断后&#xff0c;电容对继电器…

canvas绘制直角梯形(向右)

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

vue和react哪种框架使用范围更广

Vue和React都是非常流行的前端JavaScript框架&#xff0c;它们各自有着广泛的应用场景和支持者。选择使用哪一个框架往往取决于特定的项目需求、开发团队的熟悉程度以及生态系统的偏好。以下是这两个框架的一些主要特点&#xff0c;以帮助比较它们的使用范围&#xff1a; React…

计算机系统基础

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

ApiPost插件⭐️与IDEA的搭配使用,通过引入插件直接在项目里一键开测

小伙伴们大家好&#xff0c;用接口测试工具有一段时间了&#xff0c;最近发现该工具有提供插件直接可以在项目里测试接口&#xff0c;并且页面布局不输应用 目录 一、ApiPost插件介绍 二、安装插件 一、ApiPost插件介绍 Apipost 是一个用于测试和调试 API 接口的 IDEA 插件…

pytorch集智-1安装与简单使用

1 安装 1.1 简介 pytorch可用gpu加速&#xff0c;也可以不加速。gpu加速是通过cuda来实现&#xff0c;cuda是nvidia推出的一款运算平台&#xff0c;它可以利用gpu提升运算性能。 所以如果要装带加速的pytorch&#xff0c;需要先装cuda&#xff0c;再装pytorch&#xff0c;如…

【Python机器学习】构建简单的k近邻算法模型

k近邻算法是一个很容易理解的算法&#xff0c;构建模型只需要保存训练数据集。要对一个新的数据点做出预测&#xff0c;算法会在训练集中寻找与这个新数据点距离最近的数据点&#xff0c;然后将找到的数据点的标签赋值给这个新数据点。 l近邻算法中k的含义是&#xff1a;我们可…

golang学习专栏

GOLANG专栏 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教程 MySQ…

Springcloud 微服务实战笔记 Ribbon

使用 Configurationpublic class CustomConfiguration {BeanLoadBalanced // 开启负载均衡能力public RestTemplate restTemplate() {return new RestTemplate();}}可看到使用Ribbon&#xff0c;非常简单&#xff0c;只需将LoadBalanced注解加在RestTemplate的Bean上&#xff0…

设计模式_结构型模式_装饰器模式

装饰器模式和代理模式很像。 代理模式是已经知道代理谁了&#xff0c;所以只是对委托类的访问权限进行限制&#xff0c;因此用户只需要访问相应的代理类就可以。装饰器模式并不知道要装饰谁&#xff0c;所以需要传入具体的被装饰对象进行功能的添加 目的&#xff1a; 增加现有…