【10.10】队列-设计自助结算系统
一、题目
请设计一个自助结账系统,该系统需要通过一个队列来模拟顾客通过购物车的结算过程,需要实现的功能有:
get_max():获取结算商品中的最高价格,如果队列为空,则返回 -1add(value):将价格为value的商品加入待结算商品队列的尾部remove():移除第一个待结算的商品价格,如果队列为空,则返回 -1
注意,为保证该系统运转高效性,以上函数的均摊时间复杂度均为 O(1)
示例 1:
输入: ["Checkout","add","add","get_max","remove","get_max"] [[],[4],[7],[],[],[]]输出: [null,null,null,7,4,7]
示例 2:
输入: ["Checkout","remove","get_max"] [[],[],[]]输出: [null,-1,-1]
提示:
1 <= get_max, add, remove 的总操作数 <= 100001 <= value <= 10^5
二、解题思路
我们可以使用单调的双端队列来解决,该方法的精髓在于通过保持队列的单调递减顺序来高效地解决最大值查询问题。算法的关键洞见是:一旦新元素被加入队列,它之前的所有较小的元素都不再可能成为最大值。这一点通过维护一个严格递减的双端队列得以实现,具体过程如下:
核心原理
以一个数字序列例如 [1, 1, 1, 1, 2] 为例,一旦数字 2 被加入队列,所有在它之前的数字 1 都不再有可能成为最大值。这是因为在队列的出队操作中,数字 2 只会在所有数字 1 都被移除之后才可能被移除。换言之,任何时刻只要队列中有数字 1,数字 2 也必然在队列中,从而使得数字 1 对最大值的判断没有任何影响。这就揭示了维护队列单调递减的重要性——只有当队列中的每个元素都保证比它前面的元素大时,我们才能在 O(1) 的时间复杂度内查询到最大值。
实现机制
- **双端队列的应用**
使用双端队列可以从两端进行元素的添加和移除操作。在新元素加入时,我们从队列尾部开始,移除所有小于当前新元素的值,直到遇到一个更大的值或队列为空。这个过程保证了队列的单调递减特性。通过数学归纳法可以证明,如果在加入新元素之前队列是单调递减的,那么加入新元素后队列仍然是单调递减的。
- **辅助队列的配合**
除了双端队列,还需要一个辅助队列来记录所有加入的元素。这个辅助队列用来同步删除操作,确保当我们从双端队列的头部移除最大值时,辅助队列也相应地从头部移除元素。这样可以保持双端队列始终反映当前有效元素的最大值。
- **极值查询的优化**
由于队列的单调递减特性,查询当前最大值只需要简单地查看双端队列的首部元素。这样,原本需要遍历整个队列的操作被优化到了常数时间复杂度,大大提高了查询效率,特别是在需要频繁进行最大值查询的场景中。
总的来说,该算法通过巧妙地利用双端队列和辅助队列,实现了一个能够快速查询最大值的队列结构,对于需要实时处理数据并经常查询最大值的应用场景来说,这是一个极具效率的解决方案。
三、代码实现
#include <iostream>
#include <queue>
#include <deque>using namespace std;// Checkout 类,用于模拟一个结账队列,可以添加元素、移除元素以及获取队列中的最大值
class Checkout {queue<int> q; // 存储所有元素的队列deque<int> d; // 双端队列,用于维护队列中所有元素的最大值public:Checkout() {// 构造函数不需要任何操作}// 获取当前队列中的最大值int get_max() {if (d.empty())return -1; // 如果双端队列为空,则返回 -1return d.front(); // 返回双端队列的首元素,即最大值}// 向队列中添加一个新元素void add(int value) {// 从双端队列的尾部开始,移除所有小于新元素的值while (!d.empty() && d.back() < value) {d.pop_back();}d.push_back(value); // 在双端队列尾部添加新元素q.push(value); // 在队列尾部添加新元素}// 从队列中移除一个元素int remove() {if (q.empty())return -1; // 如果队列为空,则返回 -1int ans = q.front(); // 获取队列的首元素if (ans == d.front()) {d.pop_front(); // 如果队列的首元素是当前最大值,则也从双端队列中移除}q.pop(); // 从队列中移除首元素return ans; // 返回被移除的元素}
};int main() {// 示例 1Checkout checkout1;checkout1.add(4);checkout1.add(7);cout << checkout1.get_max() << endl; // 输出应为 7cout << checkout1.remove() << endl; // 输出应为 4cout << checkout1.get_max() << endl; // 输出应为 7// 示例 2Checkout checkout2;cout << checkout2.remove() << endl; // 输出应为 -1cout << checkout2.get_max() << endl; // 输出应为 -1return 0;
}
时间复杂度
-
add(int value)函数:该函数中,我们在双端队列d中添加元素之前,可能会移除一些元素。虽然这个操作看起来是在一个循环中,但每个元素最多只会被添加一次并最多被移除一次。因此,对于n次add操作,总的时间复杂度是 O(n)。这意味着单次add操作的摊还时间复杂度是 O(1)。 -
remove()函数:该函数中,我们移除队列q中的元素,并且可能会移除双端队列d中的元素(如果它是当前最大值)。这些操作都是常数时间的,因此remove的时间复杂度是 O(1)。 -
get_max()函数:该函数只是返回双端队列d的首元素,是常数时间的操作,所以get_max的时间复杂度是 O(1)。
空间复杂度
-
对于
Checkout类,主要的空间消耗来自于存储元素的队列q和双端队列d。在最坏的情况下,如果没有元素被移除,这两个数据结构中都会存储所有添加的元素。 -
如果我们添加了
n个元素,那么队列q将包含n个元素。双端队列d在最坏的情况下(即所有元素都按递减顺序添加),也会包含n个元素。因此,空间复杂度是 O(n)。
总结起来,对于 Checkout 类的每个操作,我们有:
- 时间复杂度:O(1)(对于
add,是摊还的时间复杂度) - 空间复杂度:O(n)(其中
n是添加到队列中的元素数量)
相关文章:
【10.10】队列-设计自助结算系统
一、题目 请设计一个自助结账系统,该系统需要通过一个队列来模拟顾客通过购物车的结算过程,需要实现的功能有: get_max():获取结算商品中的最高价格,如果队列为空,则返回 -1add(value):将价格为…...
Mac安装配置使用nginx的一系列问题
brew安装nginx https://juejin.cn/post/6986190222241464350 使用brew安装nginx,如下命令所示: brew install nginx 如下图所示: 2.查看nginx的配置信息,如下命令: brew info nginxFrom:xxx 这样的,是n…...
在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。
题目:在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。 延时函数分析LED首先实现8个数码管单独依次显示0~9的数字所有数码管一起同时显示0~F的值,如此往…...
00_Machine Vision_基础介绍
基础概念 由于计算机只能处理离散的数据,所以需要将连续的图片转化为离散的数据。主要包含:空间离散以及灰度值离散 空间离散:将图片的像素点离散化,即将图片的像素点转化为一个个的小方块,即为图片的分辨率。分辨率…...
组件库选择:ElementUI 还是 Ant Design
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
【Kubernetes的SpringCloud最佳实践】有Service是否还需要Eureka?
在 Kubernetes 中部署 Spring Cloud 微服务时,是否还需要 Eureka 取决于具体场景和架构设计。以下是详细的实践建议和结论: 1. Kubernetes 原生服务发现 vs Eureka Kubernetes 自身提供了完善的服务发现机制(通过 Service 资源)&…...
顺丰数据分析(数据挖掘)面试题及参考答案
你觉得数据分析人员必备的技能有哪些? 数据分析人员需具备多方面技能,以应对复杂的数据处理与解读工作。 数据处理能力:这是基础且关键的技能。数据常以杂乱、不完整的形式存在,需通过清洗,去除重复、错误及缺失值数据,确保数据质量。例如,在电商销售数据中,可能存在价…...
从运输到植保:DeepSeek大模型探索无人机智能作业技术详解
DeepSeek,作为一家专注于深度学习与人工智能技术研究的企业,近年来在AI领域取得了显著成果,尤其在无人机智能作业技术方面展现了其大模型的强大能力。以下是从运输到植保领域,DeepSeek大模型探索无人机智能作业技术的详解…...
超越LSTM!TCN模型如何精准预测股市波动(附代码)
作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话:最近我用TCN时间卷积网络预测了标普500指数(SPX)的每日回报率,发现效果远超传统方法。TCN通过因果卷积和膨胀卷积捕捉时间序列的长期依赖关…...
[每周一更]-(第133期):Go中MapReduce架构思想的使用场景
文章目录 **MapReduce 工作流程**Go 中使用 MapReduce 的实现方式:**Go MapReduce 的特点****哪些场景适合使用 MapReduce?**使用场景1. 数据聚合2. 数据过滤3. 数据排序4. 数据转换5. 数据去重6. 数据分组7. 数据统计8.**统计文本中单词出现次数****代码…...
QML初识
目录 一、关于QML 二、布局定位和锚点 1.布局定位 2.锚点详解 三、数据绑定 1.基本概念 2.绑定方法 3.数据模型绑定 四、附加属性及信号 1.附加属性 2.信号 一、关于QML QML是Qt框架中的一种声明式编程语言,用于描述用户界面的外观和行为;Qu…...
查询已经运行的 Docker 容器启动命令
一、导语 使用 get_command_4_run_container 查询 docker 容器的启动命令 获取镜像 docker pull cucker/get_command_4_run_container 查看容器命令 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run_container 容器id或容器名 …...
项目管理中的13个数据分析思维
01 信度与效度思维 信度:是指一个数据或指标自身的可靠程度,包括准确性和稳定性。 效度:是指一个数据或指标的生成,需贴合它所要衡量的事物,即指标的变化能够代表该事物的变化。 在项目管理中,信度和效度的…...
快速查看ROS节点的CPU和内存占用情况
他们可能是在排查资源泄漏的问题,所以需要监控节点的CPU和内存使用情况。可能他们遇到了节点占用过多资源导致服务器崩溃的情况,需要快速定位问题节点。现有的Linux命令方面,top和htop可以实时查看进程资源使用,但用户想要的是针对ROS节点的,可能需要更针对性的工具。ROS本…...
Centos Stream 10 根目录下的文件夹结构
/ ├── bin -> usr/bin ├── boot ├── dev ├── etc ├── home ├── lib -> usr/lib ├── lib64 -> usr/lib64 ├── lostfound ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin -> usr/sbin ├── srv ├─…...
协议_CAN协议
物理层特征 信号传输原理: CAN控制器根据CAN_L和CAN_H上的电位差来判断总线电平,总线电平分为显性电平(CAN_H与CAN_L压差 2v)、隐性电平(CAN_H与CAN_L压差 0v),发送方通过总线电平的变化&am…...
nuxt3中报错: `setInterval` should not be used on the server.
那是因为在后端渲染没有浏览器的执行环境,一些浏览器环境提供的对象和方法都无法使用,代码判断下就行。 if (import.meta.client) {setInterval(() > {}, 1000) }Import meta Nuxt API...
leetcode_深度搜索和广度搜索 101. 对称二叉树
101. 对称二叉树 给你一个二叉树的根节点 root , 检查它是否轴对称思路: 1.判断根节点的左右子树是否为空, 若都为空则返回True2.根节点的左右子树其中之一为空或子树的根节点的值不同则返回False3.分别判断根节点左右子树是否相同, 判断时, 左边子树的左节点要对应…...
QT修仙之路2-2 对话框 尚欠火候
警告对话框 相关代码 错误对话框 相关代码 消息对话框 相关代码 询问对话框 相关代码 相关代码 警告对话框 QMessageBox::warning(this,"错误","账号密码不能为空",QMessageBox::Ok);错误对话框 QMessageBox msgBox(QMessageBox::Critical,"错误…...
NFT Insider #168:The Sandbox 推出新春{金蛇礼服}套装;胖企鹅合作 LINE Minini
引言:NFT Insider 由 NFT 收藏组织 WHALE Members、BeepCrypto 联合出品, 浓缩每周 NFT 新闻,为大家带来关于 NFT 最全面、最新鲜、最有价值的讯息。每期周报将从 NFT 市场数据,艺术新闻类,游戏新闻类,虚拟…...
ZooKeeper 技术全解:概念、功能、文件系统与主从同步
引言 随着分布式系统变得越来越复杂,对协调服务的需求也在不断增长。ZooKeeper 作为一个由 Apache 维护的开源分布式协调服务框架,广泛用于 Hadoop 生态系统和其他需要协调的分布式环境中。这一系统旨在解决分布式应用中常见的挑战,如配置管…...
什么是deepseek?
AI国产免费开源强大 DeepSeek 是由国内团队开发的一款开源人工智能工具库,专注于提供高效易用的 AI 模型训练与推理能力。它既包含预训练大语言模型(如 DeepSeek-R1 系列),也提供配套工具链,助力开发者快速实现 AI 应用…...
容器服务基础
1.腾讯云容器服务 使用该服务,开发者将无需安装、运维、扩展您的集群管理基础设施,只需进行简单的API调用,便可启动和停止 Docker 应用程序,查询集群的完整状态,以及使用各种云服务。 创建集群--创建工作负载/创建ingr…...
C++基础知识(二)之数据类型、指针和内存、数组
六、C数据类型 1、sizeof运算符 sizeof运算符用于求数据类型或变量占用的内存空间。 用于数据类型:sizeof(数据类型) 用于变量:sizeof(变量名) 或 sizeof 变量名 注意: 在32位和64位操作系统中,同一种数据类型占用的内存空间…...
LLMs之DeepSeek r1:Logic-RL的简介、安装和使用方法、案例应用之详细攻略
LLMs之DeepSeek r1:Logic-RL的简介、安装和使用方法、案例应用之详细攻略 目录 Logic-RL的简介 1、Logic-RL的特点 2、性能 Logic-RL 的安装和使用方法 1、安装 2、使用方法 数据准备 基础模型 指令模型 训练执行 实现细节 Logic-RL的案例应用 Logic-RL…...
AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA的CAN FD汽车总线数据交互系统设计
目录 前言 汽车总线以及发展趋势 汽车总线技术 汽车总线发展趋势 CAN FD总线国内外研究现状 2 系统方案及CAN FD协议分析 2.1系统控制方案设计 2.2 CAN FD总线帧结构分析 2.2.1数据帧分析 2.2.2远程帧分析 2.2.3过载帧分析 2.2.4错误帧分析 2.2.5帧间隔分析 2.3位…...
【神经网络框架】非局部神经网络
一、非局部操作的数学定义与理论框架 1.1 非局部操作的通用公式 非局部操作(Non-local Operation)是该研究的核心创新点,其数学定义源自经典计算机视觉中的非局部均值算法(Non-local Means)。在深度神经网络中,非局部操作被形式化为: 其中: 1.2 与传统操作的对比分析…...
22.[前端开发]Day22-CSS单位-CSS预处理器-移动端视口
1 CSS常见单位详解 CSS中的单位 CSS中的绝对单位( Absolute length units ) CSS中的相对单位( Relative length units ) 1.em: 相对自己的font-size;如果自己没有设置, 那么会继承父元素的font-size 2.如果font-size中…...
深入讲解MyBatis
1. MyBatis 的背景和优势 背景:在 Java 开发中,传统的 JDBC 操作数据库代码繁琐,需要手动管理数据库连接、编写 SQL 语句、处理结果集等,开发效率低且容易出错。MyBatis 应运而生,它通过将 SQL 语句与 Java 代码分离&a…...
URL调用本地Ollama模型
curl http://192.168.2.247:11434/api/generate -d "{ \"model\": \"deepseek-r1:8b\", \"prompt\": \"Who r u?\" ,\"stream\":false}" 连续对话...
