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

【LeetCode】No.225. 用队列实现栈 -- Java Version

题目链接:https://leetcode.cn/problems/implement-stack-using-queues/

1. 题目介绍(225. 用队列实现栈)

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

实现 MyStack 类:

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

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 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 都保证栈不为空

【跟踪】:

进阶:你能否仅用一个队列来实现栈。

2. 题解

2.1 两个队列实现栈 – O(n)

时间复杂度O(n),空间复杂度O(n)

class MyStack {// 1. 定义两个队列对象private Queue<Integer> queue1;private Queue<Integer> queue2;// 2. 定义一个变量,用于记录当前的queue元素长度private int curSize = 0;// 3. 构造方法,创建队列对象public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}// 4. 入栈方法,如果哪个队列有值先添加到哪个,默认添加queue1public void push(int x) {if (!queue1.isEmpty()) queue1.offer(x);else if (!queue2.isEmpty()) queue2.offer(x);else queue1.offer(x);}// 5. 出栈方法public int pop() {// 判空if (empty()) return -1;// 至少有一个非空// 当queue1非空时,将queue1中size-1的元素出队存入queue2// 循环结束,queue1中只剩下一个元素,即栈顶元素(最后添加的元素)if (!queue1.isEmpty()){curSize = queue1.size();for (int i = 0; i < curSize-1; i++){queue2.offer(queue1.poll());}return queue1.poll();// queue1为空,说明queue2非空,步骤基本同上}else {curSize = queue2.size();for (int i = 0; i < curSize-1; i++){queue1.offer(queue2.poll());}return queue2.poll();}}// 6. 返回栈顶方法public int top() {// 定义一个临时值变量,用于记录queue出队值int ret = -1;// 判空if (empty()) return -1;// 至少有一个非空// 当queue1非空时,将queue1中所有的元素出队存入queue2// 同时通过临时值变量ret记录出队值,循环结束返回ret,即为栈顶元素if (!queue1.isEmpty()){curSize = queue1.size();for (int i = 0; i < curSize; i++){//System.out.println(queue1.size());ret = queue1.poll(); queue2.offer(ret);}System.out.println(ret);return ret;// queue1为空,说明queue2非空,步骤基本同上}else {curSize = queue2.size();for (int i = 0; i < curSize; i++){ret = queue2.poll(); queue1.offer(ret);}return ret;}}// 判空方法,queue1与queue2全为空,则为空public boolean empty() {return queue1.isEmpty() && queue2.isEmpty();}
}/*** Your MyStack object will be instantiated and called as such:* MyStack obj = new MyStack();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.top();* boolean param_4 = obj.empty();*/

在这里插入图片描述
改进:(官方题解)
在这里插入图片描述
这里的改进点在于:push方法的巧妙设置,数据首先会存入queue2,并检查queue1是否为空,如果不为空,则将queue1中的元素全部出队,并存入queue2;然后借助临时变量交换queue1和queue2,保证每次push方法后,queue2始终为空,queue1为真正的栈结构,做到后进先出。

class MyStack {Queue<Integer> queue1;Queue<Integer> queue2;/** Initialize your data structure here. */public MyStack() {queue1 = new LinkedList<Integer>();queue2 = new LinkedList<Integer>();}/** Push element x onto stack. */public void push(int x) {queue2.offer(x);while (!queue1.isEmpty()) {queue2.offer(queue1.poll());}Queue<Integer> temp = queue1;queue1 = queue2;queue2 = temp;}/** Removes the element on top of the stack and returns that element. */public int pop() {return queue1.poll();}/** Get the top element. */public int top() {return queue1.peek();}/** Returns whether the stack is empty. */public boolean empty() {return queue1.isEmpty();}
}

2.2 一个队列实现栈 – O(n)

时间复杂度O(n),空间复杂度O(n)
在这里插入图片描述
核心方法:当有新元素加入时,将原来的元素依次出队并重新入队,让队列中的元素始终保持倒序的状态。

class MyStack {Queue<Integer> queue;/** Initialize your data structure here. */public MyStack() {queue = new LinkedList<Integer>();}/** Push element x onto stack. */public void push(int x) {int n = queue.size();queue.offer(x);for (int i = 0; i < n; i++) {queue.offer(queue.poll());}}/** Removes the element on top of the stack and returns that element. */public int pop() {return queue.poll();}/** Get the top element. */public int top() {return queue.peek();}/** Returns whether the stack is empty. */public boolean empty() {return queue.isEmpty();}
}

在这里插入图片描述

3. 参考资料

[1] 用队列实现栈(官方题解)-- 部分代码来源
[2] 【LeetCode】No.232. 用栈实现队列 – Java Version(相似题目)
[3] 【LeetCode】剑指 Offer 09. 用两个栈实现队列 p68 – Java Version(相似题目)

http://www.lryc.cn/news/14096.html

相关文章:

  • 45个写规范代码的小技巧
  • MindFusion Diagramming for Java, 最新版 Crack
  • 中间件安全—Apache常见漏洞
  • Spring IOC 容器 Bean 加载过程
  • 【DRF】Django Rest Framework(5.DRF中的通用视图类-GenericAPIView方法说明与使用说明)
  • STM32 OTA应用开发——自制BootLoader
  • 时域和频域的简单理解
  • 华为OD机试 - 第 K 个最小码值的字母 | 机试题算法思路 【2023】
  • 离散数学笔记_第一章:逻辑和证明(1)
  • Rust FFI 与C语言互相调用
  • 从全局变量寻找到Tomcat回显方式
  • Tapdata Connector 实用指南:数据入仓场景之数据实时同步到 BigQuery
  • 关于机器人状态估计(12)-VIO/VSLAM的稀疏与稠密
  • Python每日一练(20230220)
  • 技术总监的“技术提升”
  • kettle安装部署_简单认识_Spoon勺子界面---大数据之kettle工作笔记002
  • 第三章 Kafka生产问题总结及性能优化实践
  • Comparable和Comparator的区别
  • 全15万字丨PyTorch 深度学习实践、基础知识体系全集;忘记时,请时常回顾。
  • 简洁易用的记账小程序——微点记账
  • Windows平台上达梦数据库的ODBC安装与配置
  • 哈希表的介绍
  • spring cloud gateway 实现redis动态路由及自动项目路由上报
  • c++函数对象(仿函数)、谓词、内建函数对象
  • 物联网对供应链管理的影响
  • c++ 那些事 笔记
  • 心跳机制Redis
  • 蓝桥杯算法训练合集十七 1.数字反转2.试题39713.矮人采金子4.筛法5.机器指令
  • 第一章 初识 Spring Security
  • 2023-02-20 关于回朔的思考