当前位置: 首页 > news >正文

算法-每日一题(DAY15)用队列实现栈

1.题目链接

225. 用队列实现栈 - 力扣(LeetCode)

2.题目描述

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空

3.解题思路

对于这道题我们使用了两个队列(q1 和 q2)的双队列策略。初始化时,两个队列为空。对于入栈操作(push),元素直接被推入队列 q1。出栈操作(pop)则通过将队列 q1 中的所有元素逐个转移到队列 q2 中,直到 q1 中只剩下一个元素,这样单独剩下的元素即为要弹出的栈顶元素。随后将 q2 中的元素全部转回 q1,保持队列的栈结构。获取栈顶元素(top)的方法直接返回 q1 的最后一个元素。检查栈是否为空(empty)则简单地返回 q1 是否为空。通过这种方法,栈的基本操作得以利用队列的特性有效地实现,灵活地保持了后进先出的原则。

更通俗的讲,想象你有两个箱子(q1 和 q2)。你将东西(元素)从箱子 q1 放入箱子 q2,但是你不想每次都手动把东西搬回去。所以每当你从栈里拿东西时,你就把 q1 里的东西搬到 q2,直到剩下一个东西,然后那就是栈顶元素。拿出栈顶元素后,把 q2 的东西再搬回 q1,让栈继续运作。

4.题解代码

class MyStack {
public:queue<int> q1, q2; // 定义两个队列 q1 和 q2,用于实现栈的功能MyStack()// 构造函数,初始化栈{}void push(int x)// push 函数:将元素 x 压入栈中{q1.push(x);// 直接将元素 x 添加到队列 q1 的末尾}int pop()// pop 函数:从栈中弹出元素并返回{// 将 q1 中的元素全部移到 q2,直到 q1 剩下最后一个元素while (q1.size() > 1) {// 将 q1 的前面的元素移动到 q2q2.push(q1.front());q1.pop();} int res = q1.front();// 保存 q1 中的最后一个元素(栈顶元素)q1.pop(); // 弹出栈顶元素(即来自 q1 的最后一个元素)q1 = q2;// 将 q2 中的元素全部移动回 q1while (!q2.empty()) {q2.pop();// 清空 q2,准备下一次操作}return res;// 返回被弹出的元素}int top()// top 函数:返回栈顶的元素但不弹出它{return q1.back();// 由于 q1 是在 push 时添加元素的,top 方法直接访问 q1 队列中的最后一个元素}bool empty()// empty 函数:检查栈是否为空{return q1.empty();// 通过检查 q1 是否为空来判断栈是否为空}
};

5.示例演算

步骤操作队列1状态 (队首← →队尾)队列2状态 (队首← →队尾)栈状态 (栈底← →栈顶)操作详情说明
初始-[][][]初始状态
1push(1)[1][][1]将1加入队列1
2push(2)[1,2][][1,2]将2加入队列1
3push(3)[1,2,3][][1,2,3]将3加入队列1
4pop()[][1,2][1,2]关键步骤
1. 将队列1前n-1个元素(1,2)转移到队列2
2. 弹出队列1的最后一个元素(3)
5push(4)[][1,2,4][1,2,4]将4加入当前非空队列(队列2)
6pop()[1,2][][1,2]关键步骤
1. 将队列2前n-1个元素(1,2)转移到队列1
2. 弹出队列2的最后一个元素(4)
7pop()[1][][1]关键步骤
1. 将队列1前n-1个元素(1)转移到队列2
2. 弹出队列1的最后一个元素(2)

6.复杂度计算

时间复杂度:

操作时间复杂度说明
pushO(1)直接插入队列末尾
popO(n)需要转移n−1个元素 + 队列深拷贝O(n) + 清空队列O(n)
topO(1)直接访问队列尾部元素
emptyO(1)简单判断队列是否为空

空间复杂度:总空间复杂度为 O(n),因为两个队列最多同时存储 n 个元素(在执行 push 操作时会临时存储)。此外,额外空间复杂度为 O(1),因为指针的交换和操作不需要额外的存储开销。

http://www.dtcms.com/a/351072.html

相关文章:

  • SQLBot 智能问数、数据洞察逻辑拆解
  • 【GM3568JHF】FPGA+ARM异构开发板 应用编辑及源码下载
  • 零基础也能照做的WordPress网站安全漏洞修复 + 高级优化保姆级教程。
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第七章知识点问答(22题)
  • Netty源码—性能优化和设计模式
  • HarmonyOS 中的 @Prop 装饰器:深入理解单向数据传递
  • 网站如何被搜索引擎收录(Google、Bing、百度等)
  • [特殊字符]Windows 资源监视器使用指南:查端口以后不用敲命令了
  • AI解决生活小事系列——用AI给我的电脑做一次“深度体检”
  • 【LeetCode 热题 100】31. 下一个排列
  • Python之matplotlib 基础五:绘制饼状统计图
  • 有鹿机器人:为城市描绘清洁新图景的智能使者
  • Linux IO模型:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO
  • 绿算技术解密金融科技安全:高性能计算与存储驱动金融防火墙新时代
  • 系统安全难题咋解?低代码给出新思路
  • 打破技术壁垒的先进制造框架的智慧工业开源了
  • 医疗巡诊车5G专网路由器应用
  • 360智脑开源优化排序模型——360Zhinao-1.8B-Reranking本地部署教程,提升检索质量,减少大模型“幻觉”现象
  • Windows编程日志4——消息队列和消息处理
  • Hive的核心架构
  • Go语言模块开发
  • 从线到机:AI 与多模态交互如何重塑 B 端与 App 界面设计
  • S-HUB实现泛微E9与飞书对接
  • Redisson详解:高性能redis客户端,超详细!
  • MyBatis 初识:框架定位与核心原理——SQL 自由掌控的艺术
  • 【资讯】国内免费/开源大模型对比及获得途径总结
  • 书生大模型InternLM2:从2.6T数据到200K上下文的开源模型王者
  • 实体店转型破局之道:新零售社区商城小程序开发重构经营生态
  • kafka消费顺序保障
  • Kafa面试经典题--Kafka为什么吞吐量大,速度快