【面试高频算法解析】算法练习8 单调队列
前言
本专栏旨在通过分类学习算法,使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目,帮助您深度理解每种算法,避免出现刷了很多算法题,还是一知半解的状态
专栏导航
- 二分查找
- 回溯(Backtracking)
- 双指针
- 滑动窗口
- 深度优先搜索
- 广度优先搜索
- 贪心算法
- 单调队列
- 堆(Heap)
- 分治(Divide and Conquer)
- 动态规划
算法解析
单调队列是一种特殊的队列数据结构,其主要特点是保持队列元素的单调性(单调递增或单调递减)。在单调队列中,新元素的加入可能会导致队列中的一些元素被移除,以维护队列的单调性。
单调队列通常用于解决滑动窗口类问题,如寻找窗口内的最大值或最小值。使用单调队列能够在常数时间内获取窗口的最大或最小元素,从而有效地优化算法的时间复杂度。
以下是单调队列的两种主要操作:
-
入队(Push):
当新元素加入队列时,从队列尾部开始,移除所有破坏队列单调性的元素,然后将新元素加入队列尾部。对于单调递增队列,如果新元素小于队尾元素,则队尾元素被移除;对于单调递减队列,如果新元素大于队尾元素,则队尾元素被移除。 -
出队(Pop):
当需要移除队列头部元素时(例如滑动窗口移动导致窗口头部元素不再属于当前窗口),如果队头元素等于需要移除的元素,则将其出队。
单调队列可以用双端队列(deque)来实现,因为双端队列允许从两端高效地添加和移除元素。
下面是一个使用 Python 中的 collections.deque 实现单调递减队列的示例,该队列用于找到滑动窗口的最大值:
from collections import dequeclass MonotonicQueue:def __init__(self):self.deque = deque()def push(self, value):# 移除所有小于即将入队的值的元素while self.deque and self.deque[-1] < value:self.deque.pop()self.deque.append(value)def max(self):# 队列的最大值始终位于队头return self.deque[0]def pop(self, value):# 如果队头元素是即将移除的值,则出队if self.deque and self.deque[0] == value:self.deque.popleft()# 示例:滑动窗口最大值
def max_sliding_window(nums, k):window = MonotonicQueue()result = []for i, value in enumerate(nums):if i < k - 1:window.push(value)else:# 滑动窗口向右移动window.push(value)result.append(window.max()) # 记录当前窗口的最大值# 移除窗口最左边的值window.pop(nums[i - k + 1])return result# 使用示例
nums = [1,3,-1,-3,5,3,6,7]
k = 3
print(max_sliding_window(nums, k)) # 输出 [3,3,5,5,6,7]
在这个例子中,我们定义了一个 MonotonicQueue 类来模拟单调递减队列,并在滑动窗口中使用它来找到每个窗口的最大值。当新元素加入时,队列中所有小于新元素的值都会被移除,以保持队列的单调递减性。当窗口滑动时,如果队头的元素是窗口最左边即将移出窗口的值,则将其从队列中移除。
实战练习
购买水果需要的最少金币数
你在一个水果超市里,货架上摆满了玲琅满目的奇珍异果。
给你一个下标从 1 开始的数组 prices ,其中 prices[i] 表示你购买第 i 个水果需要花费的金币数目。
水果超市有如下促销活动:
如果你花费 price[i] 购买了水果 i ,那么接下来的 i 个水果你都可以免费获得。
注意 ,即使你 可以 免费获得水果 j ,你仍然可以花费 prices[j] 个金币去购买它以便能免费获得接下来的 j 个水果。
请你返回获得所有水果所需要的 最少 金币数。
示例 1:
输入:prices = [3,1,2]
输出:4
解释:你可以按如下方法获得所有水果:
- 花 3 个金币购买水果 1 ,然后免费获得水果 2 。
- 花 1 个金币购买水果 2 ,然后免费获得水果 3 。
- 免费获得水果 3 。
注意,虽然你可以免费获得水果 2 ,但你还是花 1 个金币去购买它,因为这样的总花费最少。
购买所有水果需要最少花费 4 个金币。
示例 2:
输入:prices = [1,10,1,1]
输出:2
解释:你可以按如下方法获得所有水果:
- 花 1 个金币购买水果 1 ,然后免费获得水果 2 。
- 免费获得水果 2 。
- 花 1 个金币购买水果 3 ,然后免费获得水果 4 。
- 免费获得水果 4 。
购买所有水果需要最少花费 2 个金币。
提示:
1 <= prices.length <= 1000
1 <= prices[i] <= 105
官方题解
环形子数组的最大和
给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 。
环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。
子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], …, nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。
示例 1:
输入:nums = [1,-2,3,-2]
输出:3
解释:从子数组 [3] 得到最大和 3
示例 2:
输入:nums = [5,-3,5]
输出:10
解释:从子数组 [5,5] 得到最大和 5 + 5 = 10
示例 3:
输入:nums = [3,-2,2,-3]
输出:3
解释:从子数组 [3] 和 [3,-2,2] 都可以得到最大和 3
提示:
n == nums.length
1 <= n <= 3 * 104
-3 * 104 <= nums[i] <= 3 * 104
官方题解
相关文章:
【面试高频算法解析】算法练习8 单调队列
前言 本专栏旨在通过分类学习算法,使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目,帮助您深度理解每种算法,避免出现刷了很多算法题,还是一知半解的状态 专栏导航 二分查找回溯(Backtracking&…...
ATTCK视角下的信息收集:Sysmon检测
目录 1、简介 2、使用Sysmon 3、检测Sysmon是否安装运行 4、检测Sysmon是否被卸载 5、使Sysmon在终端隐匿运行的技术 1、简介 Sysmon(系统监视器)是由windows sysinternals 出品的Sysinternals 系列工具中的一个 它是windows系统服务和设备驱动程…...
02、Kafka ------ 配置 Kafka 集群
目录 配置 Kafka 集群配置步骤启动各Kafka节点 配置 Kafka 集群 启动命令: 1、启动 zookeeper 服务器端 小黑窗输入命令: zkServer 2、启动 zookeeper 的命令行客户端工具 (这个只是用来看连接的节点信息,不启动也没关系&#…...
2024年全球网络安全预测报告
1.Gartner Gartners Top Strategic Predictions for 2024 and Beyond《Gartner顶级战略预测:2024年及未来》 https://www.gartner.com/en/articles/gartner-s-top-strategic-predictions-for-2024-and-beyond 2.IDC Top 10 Worldwide IT Industry 2024 Predict…...
Qt - QML与C++数据交互详解
文章目录 1 . 前言2 . Qml调用C的变量3 . Qml调用C的类4 . Qml调用C的方法5 . Qml接收C的信号6 . C接收Qml的信号(在Qml中定义信号槽)7 . C接收Qml的信号(在C中定义信号槽)8 . C调用Qml的函数9 . 总结 【极客技术传送门】 : https…...
Kettle Local引擎使用记录(一)(基于Kettle web版数据集成开源工具data-integration源码)
Kettle Web 📚第一章 前言📚第二章 demo源码📗pom.xml引入Kettle引擎核心文件📗java源码📕 controller📕 service📕 其它📕 maven settings.xml 📗测试📕 测试…...
Java--业务场景:在Spring项目启动时加载Java枚举类到Redis中(补充)
文章目录 前言步骤测试结果 前言 通过Java–业务场景:在Spring项目启动时加载Java枚举类到Redis中,我们成功将Java项目里的枚举类加载到Redis中了,接下来我们只需要写接口获取需要的枚举值数据就可以了,下面一起来编写这个接口吧。 步骤 在…...
WPF 基础入门(资源字典)
资源字典 每个Resources属性存储着一个资源字典集合。如果希望在多个项目之间共享资源的话,就可以创建一个资源字典。资源字段是一个简单的XAML文档,该文档就是用于存储资源的,可以通过右键项目->添加资源字典的方式来添加一个资源字典文件…...
文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑电氢耦合和碳交易的电氢能源系统置信间隙鲁棒规划》
本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这标题涉及到一个复杂的能源系统规划问题,其中考虑了电氢耦合、碳交易和置信间隙鲁棒规划。以下是对标题各个部分的解读: 电氢耦…...
ubuntu设定时间与外部ntp同步
前言 在 Ubuntu 上,你可以通过配置 systemd-timesyncd 服务来与外部 NTP 服务器同步系统时间。下面是设置的步骤: 安装 NTP 工具: 如果你的系统中没有安装 ntpdate 工具,可以使用以下命令安装: sudo apt-get updat…...
DataFrame详解
清洗相关的API 清洗相关的API: 1.去重API: dropDupilcates 2.删除缺失值API: dropna 3.替换缺失值API: fillna 去重API: dropDupilcates dropDuplicates(subset):删除重复数据 1.用来删除重复数据,如果没有指定参数subset,比对行中所有字段内容,如果全部相同,则认为是重复数据,…...
控制障碍函数(Control Barrier Function,CBF) 三、代码
三、代码实现 3.1、模型 这是一个QP问题,所以我们直接建模 这其实还是之前的那张图,我们把这个大的框架带入到之前的那个小车追击的问题中去,得到以下的一些具体的约束条件 CLF约束 L g V ( x ) u − δ ≤ − L f V ( x ) − λ V ( x ) …...
哈希表-散列表数据结构
1、什么是哈希表? 哈希表也叫散列表,哈希表是根据关键码值(key value)来直接访问的一种数据结构,也就是将关键码值(key value)通过一种映射关系映射到表中的一个位置来加快查找的速度,这种映射关系称之为哈希函数或者散列函数&…...
C# 强制类型转换和as区别和不同使用场景
文章目录 1.强制类型转换2. as 运算符3.实例总结: 在C#中,as 和 强制类型转换(例如 (T)value)的主要区别在于它们处理类型转换不成功时的行为和适用场景: 1.强制类型转换 使用语法:Type variable (Type)…...
什么是 DDoS 攻击
布式拒绝服务 (DDoS) 攻击是一种恶意尝试,通过大量互联网流量淹没目标或其周围基础设施,从而破坏目标服务器、服务或网络的正常流量。 DDoS 攻击通过利用多个受感染的计算机系统作为攻击流量源来实现有效性。被利用的机器可以包括计算机和其他网络资源。 从高层来看,DDoS 攻…...
c++隐式类型转换与explicit
我们知道,一个float与int做运算时,系统会首先个int类型转换为float类型之后再进行运算,这种隐式类型转换也会发生在类中 看以下例子,定义一个类 class myTime { public:int Hour;myTime() {};myTime(int h) :Hour(h) {}; }; 在…...
BERT Intro
继续NLP的学习,看完理论之后再看看实践,然后就可以上手去kaggle做那个入门的project了orz。 参考: 1810.04805.pdf (arxiv.org) BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili (强推!)2023李宏毅讲解大模型鼻祖BERT,一小时…...
“To-Do Master“ GPTs:重塑任务管理的趣味与效率
有 GPTs 访问权限的可以点击链接进行体验:https://chat.openai.com/g/g-IhGsoyIkP-to-do-master 部署私人的 To-Do Master 教程:https://github.com/Reborn14/To-Do-Master/tree/main 引言 在忙碌的日常生活中,有效地管理日常任务对于提高生…...
npm安装vue,添加淘宝镜像
如果是第一次使用命令栏可能会遇到权限问题。 解决vscode无法运行npm和node.js命令的问题-CSDN博客 安装 在vscode上面的导航栏选择terminal打开新的命令栏 另外可能会遇到网络或者其他的问题,可以添加淘宝镜像 npm install -g cnpm --registryhttps://registry.…...
LeetCode 2707. 字符串中的额外字符
一、题目 1、题目描述 给你一个下标从 0 开始的字符串 s 和一个单词字典 dictionary 。你需要将 s 分割成若干个 互不重叠 的子字符串,每个子字符串都在 dictionary 中出现过。s 中可能会有一些 额外的字符 不在任何子字符串中。 请你采取最优策略分割 s ÿ…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
