java数据结构与算法刷题-----LeetCode239. 滑动窗口最大值

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

在这里插入图片描述

1. 法一:指针法

解题思路
  1. 我们以每一个窗口来看,找到每个窗口的最大值
  2. 那么找到最大值后,会面临一些情况。就是窗口滑动后,会从左边少一个元素,右边多一个元素
  3. 首先,如果右边多出来的,比当前最大值大的话,那它一定是新的最大值。因为上一次窗口中最大为max。而新加了一个右边的,比max大,那么右边这个就是最大的
  4. 如果右边的没有当前max大。那么就考虑左边,如果左边少了一个后,新的最左边结点和max一样,那么左边这个就是新最大值
  5. 如果刚好,上一次的max,在滑动窗口后,不在窗口范围了,那么没办法,只能遍历窗口元素,找到新的最大值
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
代码:时间复杂度O(n),空间复杂度O(1)

在这里插入图片描述

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int left = 0;//滑动窗口左边界
        int right = k - 1;//滑动从窗口右边界
        int maxIndex = -1;//max元素下标
        int max = Integer.MIN_VALUE;//max - 1 = Integ.MAX_VALUE;

        int[] res = new int[nums.length - k + 1];//结果数组

        while (right < nums.length) {//还可以滑动就继续
            if (maxIndex > left) {//如果max在left右边
                if (nums[right] > max - 1) {//判断是否新添加元素>max
                    maxIndex = right;//如果right新元素>max就让max指向right
                    max = nums[maxIndex];
                }
            } else if (nums[right] > max - 1) {//如果max不在left右边,但是新添加元素,刚好>max
                maxIndex = right;//那么right一定新窗口是最大值,因为max是旧窗口的最大值
                max = nums[maxIndex];
            }else if (nums[left] >= max - 1 ) {//如果max不在left右边,而且right不是最大值,那么看看left是否是最大值
                maxIndex = left;//区域减少了一个值,添加一个right,right不是最大值,那就看看left是不是最大值
                max = nums[left];//是,就让max指向left
            }else {//上面条件都不成立,最大值既不是right也不是left,而是在中间的话。就只能循环找了
                maxIndex = left;
                max = nums[maxIndex];
                for (int i = left + 1; i <= right; i++) {
                    if (nums[i] > max - 1) {
                        maxIndex = i;
                        max = nums[maxIndex];
                    }
                }
            }
            res[left] = max;//每次都保存最大值
            left++;//滑动窗格
            right++;//滑动窗格
        }
        return res;
    }
}

2. 法二:单调队列

解题思路
  1. 每一个元素的下标都会从右端插入队列
  2. 如果插入时,队列前面的元素小于当前插入元素。说明它们不会是当前窗口最大值,我们将前面比它小的取出。然后插入当前元素
  3. 因为每次我们都将前面较小的去除了,所以最左边的元素永远是当前最大的。
  4. 但是最左边的这个下标,如果不是当前窗口范围内的下标,就先去除。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
代码:时间复杂度O(n),空间复杂度O(n)

在这里插入图片描述

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        Deque<Integer> deque = new LinkedList<Integer>();//单调队列保存下标 first <--|  队列  |--> last
        //处理第一个窗口
        for (int i = 0; i < k; ++i) {//将k个元素的下标放入单调队列
            //如果队列不为空,新元素比前面的元素大,就将前面比它小的元素取出
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();//将前面小的取出
            }
            deque.offerLast(i);//将当前值的下标放入队列,保证它前面都是值比它大的下标
        }
        int[] ans = new int[n - k + 1];//答案数组,需要n-k+1个答案,也就是一共n-k+1个窗口
        ans[0] = nums[deque.peekFirst()];//将刚刚处理的第一个窗口结果放入ans[0]
        //处理剩下的窗口
        for (int i = k; i < n; ++i) {
            //如果队列不为空,新元素比前面的元素大,就将前面比它小的元素取出
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();//将前面小的取出
            }
            deque.offerLast(i);//将当前值的下标放入队列,保证它前面都是值比它大的下标
            while (deque.peekFirst() <= i - k) {//如果左边界的下标已经不在当前窗口内
                deque.pollFirst();//将其出队列
            }
            ans[i - k + 1] = nums[deque.peekFirst()];//因为我们一直都只保留大的值,所以first就是当前窗口最大值
        }
        return ans;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux+Win双系统远程重启到Win

背景 电脑安装了双系统&#xff08;ubuntu 22.04 win11&#xff09;&#xff0c;默认进入ubuntu系统。给电脑设置了WoL(Wake-on-LAN)&#xff0c;方便远程开机远程控制。 但是ubuntu的引导程序grub无法远程控制&#xff0c;远程开机会默认进入ubuntu。 虽然说可以进入ubuntu后…

【STM32】硬件SPI读写W25Q64芯片

目录 基础知识回顾&#xff1a; SPI外设简介 SPI框图 主模式全双工连续传输 非连续传输 初始化SPI外设 核心代码 - 交换一个字节 硬件接线图 Code 程序配置过程 MySPI.c MySPI.h W25Q64.c W25Q64.h W25Q64_Ins.h main.c 基础知识回顾&#xff1a; 【STM32】SP…

《UE5_C++多人TPS完整教程》学习笔记19 ——《P20 我们子系统的回调函数(Callbacks to Our Subsystem)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P20 我们子系统的回调函数&#xff08;Callbacks to Our Subsystem&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&…

【XR806开发板试用】+移植rosserial到XR806

1 XR806简介 板子来源于极术社区的试用&#xff0c;XR806的在线网址 其主要参数&#xff1a; 主控XR806AF2LDDRSIP 288KB SRAM存储SIP 160KB Code ROM. SIP 16Mbit Flash.天线板载WiFi/BT双天线&#xff0c;可共存按键reboot按键 1&#xff0c;功能按键 1灯红色电源指示灯 1…

如何在wxPython应用程序中使用Panda3D

我们知道wxPython提供了丰富的工具和部件来构建用户界面&#xff0c;如果当我们整合wxPython和Panda3D可以创建出功能丰富且交互性强的应用程序&#xff0c;可以创建出强大而丰富的用户界面和3D场景。这样做的主要挑战在于将两个库整合到一个应用程序中&#xff0c;同时确保它们…

【.NET Core】深入理解async 和 await 理解

【.NET Core】深入理解async 和 await 理解 文章目录 【.NET Core】深入理解async 和 await 理解一、概述二、async异步执行机制理解三、async与await应用3.1 async与await简单应用3.2 带有返回值async与await应用 四、async和await中常见问题总结4.1 当方法用async标识时&…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第10章 项目进度管理(六)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

跨境云手机如何简化tiktok运营流程

如今&#xff0c;tiktok已经成为世界范围内都非常流行的社交媒体平台。然而在大多数情况下&#xff0c;由于网络原因&#xff0c;tiktok无法在国内使用&#xff0c;但依然有越来越多的人注册tiktok号码、建立tiktok矩阵。原因是tiktok仍然有大量的流量可供商业使用&#xff0c;…

day04-股票K线功能实现

股票K线功能实现 今日目标 1.理解股票T和T-1概念&#xff0c;实现成交量对比功能; 2.理解个股涨跌幅度统计功能; 2.1 分析业务&#xff0c;SQL落地; 2.2 完善不存在数据的区间默认回显功能; 3.理解个股分时线业务&#xff0c;并实现功能; 4.理解个股日K线业务&#xff0c;并实…

使用傅里叶实现100倍的压缩效果(附Python源码)

傅里叶变换&#xff08;Fourier Transform&#xff09;是一种将一个函数&#xff08;在时间或空间域&#xff09;转换为另一个函数&#xff08;在频率域&#xff09;的数学变换方法。它在信号处理、图像处理、通信等领域有广泛应用。 实现过程 将傅里叶系数核心的1%保留&…

从零开始手写mmo游戏从框架到爆炸(十五)— 命令行客户端改造

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 到现在&#xff0c;我们切实需要一个客户端来完整的进行英雄选择&#xff0c;选择地图&#xff0c;打怪等等功能。所以我们需要把之前极为简陋的客户端改造一下。 首先…

0成本部署github前端项目流程

0成本部署github纯前端项目流程 对业内来说应该是一个比较常规的操作&#xff0c;对于新手来说进行过一次应该就很难忘记了&#xff0c;但很多人仍然是不会的&#xff0c;认为部署项目很难&#xff0c;很专业&#xff0c;其实现在由于这些厂商的努力&#xff0c;大众&#xff…

js设计模式:装饰者模式

作用: 可以给原有对象的身上添加新的属性方法 可以让对象或者组件进行扩展 示例: class Person{constructor(name,selfSkill){this.name namethis.selfSkill selfSkill}run 会走路}//所有人类都有的共同特性和技能let wjt new Person(王惊涛,写代码)let mashi new Pers…

Python实现KDJ指标计算:股票技术分析的利器系列(3)

Python实现KDJ指标计算&#xff1a;股票技术分析的利器系列&#xff08;3&#xff09; 介绍算法解释 代码rolling函数介绍计算LLV&#xff08;最低价最小值&#xff09;和HHV&#xff08;最高价最大值&#xff09;计算RSV计算SMA&#xff08;简单移动平均&#xff09; 完整代码…

micro-app以UMD js链接方式引入使用

npm 下载好micro-zoe/micro-app后&#xff0c;找到index.umd.js&#xff1a; 新建一个测试html&#xff0c;引入并使用&#xff1a; 参考&#xff1a; 微组件实践 - 掘金

八、计算机视觉-边界填充

文章目录 前言一、原理二、具体的实现 前言 在Python中使用OpenCV进行边界填充&#xff08;也称为zero padding&#xff09;是一种常见的图像处理操作&#xff0c;通常用于在图像周围添加额外的像素以便进行卷积或其他操作。下面是使用OpenCV进行边界填充的基本原理和方法 一…

答题抽奖活动怎么做_一场智慧与幸运的碰撞

答题抽奖&#xff0c;知识变现&#xff0c;一场智慧与幸运的碰撞&#xff01; 在这个信息爆炸的时代&#xff0c;如何吸引人们的注意力&#xff0c;成为每个营销者都需要面对的挑战。而答题抽奖活动&#xff0c;以其独特的魅力&#xff0c;正成为越来越多品牌吸引用户、提升用…

智能无人仓|加快步伐 河北沃克HEGERLS将突破与创新“常态化”

物流的发展涉及工业、商业各个领域&#xff0c;涵盖原材料&#xff0c;生产成品从起点到终点的全过程&#xff0c;在室内物流操作上涵盖了收、发、存、拣等作业。近年来&#xff0c;由于人工成本的提高&#xff0c;基础劳动力取得的难度不断地加大&#xff0c;自动化和智能化逐…

pytest 框架自动化测试

随笔记录 目录 1. 安装 2. 安装pytest 相关插件 2.1 准备阶段 2.2 安装 2.3 验证安装成功 3. pytest测试用例的运行方式 3.1 主函数模式 3.1.1 主函数执行指定文件 3.1.2 主函数执行指定模块 3.1.3 主函数执行某个文件中的某个类、方法、函数 3.1.4 主函数执行生…

『运维备忘录』之 SSH 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等知识&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…