【算法挑战】用栈实现队列(含解析、源码)

232.用栈实现队列

https://leetcode-cn.com/problems/implement-queue-using-stacks/

  • 232.用栈实现队列
    • 题目描述
    • 方法 1
      • 思路
      • 复杂度
      • 代码
    • 方法 2
      • 思路
      • 复杂度
      • 代码(JavaScript/C++)

题目描述

使用栈实现队列的下列操作:push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
示例:MyQueue queue = new MyQueue();queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false
说明:你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法 1

思路

由于队列是 FIFI (先进先出),而栈是 FILO (先进后出)。如果要用栈来模拟队列,则每次往模拟队列增加元素的时候,这个元素需要放在栈底,因为它是最后才会出列。

方法之一是,每次需要往模拟队列尾端 push 一个新元素时:

  • 先把栈中的全部元素暂时取出
  • 将新元素入栈到栈底
  • 再将刚刚取出来元素重新入栈

因此我们还需要一个辅助栈来存暂时取出来的元素。

复杂度

  • 时间复杂度:入列操作是 O ( n ) O(n) O(n),每次入列时,除新增元素外,每个元素都需要分别出栈入栈 2 次 (从模拟队列的栈中弹出,压入辅助栈,再从辅助栈弹出,压入队列模拟栈)。压入、弹出操作的时间复杂度都是 O ( 1 ) O(1) O(1),所以总的时间复杂度差不多是 O ( 4 n ) O(4n) O(4n),忽略掉常数,最后得到 O ( n ) O(n) O(n)。出列操作是 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( n ) O(n) O(n),n 是队列的大小,需要一个大小为 n 的栈来模拟队列,还需要一个大小为 n 的辅助空间,但总的空间复杂度还是 O ( n ) O(n) O(n)

代码

JavaScript Code

class MyQueue {constructor() {this.stack = [];}push(x) {const helper = [];while (!this.empty()) {helper.push(this.stack.pop());}this.stack.push(x);while (helper.length) {this.stack.push(helper.pop());}}peek() {return this.stack[this.stack.length - 1];}pop() {return this.stack.pop();}empty() {return this.stack.length === 0;}
}

方法 2

思路

方法 1 是在元素入列的时候,就考虑好了它出列的顺序,但我们还可以转换一下思路,在元素需要出列的时候再来考虑这个问题,这样的话:

  1. 入列时,直接 push 到栈中;
  2. 出列时,由于先入列的元素在栈底,需要先把其他元素弹出,依次压入辅助栈;
  3. 栈底元素弹出,出列;
  4. 刚才出栈的其他元素依次从辅助栈弹出,重新压入模拟栈。

再仔细想想的话:

  • 第 2 步中,辅助栈中的元素出栈顺序刚好就是队列的出列顺序;
  • 所以到第 4 步的时候,我们根本没必要把元素再从辅助栈转移到模拟栈;
  • 下一次 pop 操作时,直接从辅助栈弹出元素就可以了;
  • 如果辅助栈中没有元素了,我们再重复第 2 步。

这样的话,我们的队列元素其实是用了两个栈来储存,所以在判断队列是否为空的时候,两个栈都要考虑进去。

复杂度

  • 时间复杂度:入列是 O ( 1 ) O(1) O(1),出列最差的情况就是每个元素都要从模拟栈中弹出,压入辅助栈,再从辅助栈中弹出,所以是 O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n),n 为队列大小。

代码(JavaScript/C++)

JavaScript Code

class MyQueue {constructor() {this.stack = new MyStack();this.helper = new MyStack();}push(x) {this.stack.push(x);}peek() {if (this.helper.empty()) {while (!this.stack.empty()) {this.helper.push(this.stack.pop());}}return this.helper.peek();}pop() {if (this.helper.empty()) {while (!this.stack.empty()) {this.helper.push(this.stack.pop());}}return this.helper.pop();}empty() {return this.stack.empty() && this.helper.empty();}
}class MyStack {constructor() {this.stack = [];}push(x) {this.stack.push(x);}pop() {return this.stack.pop();}peek() {return this.stack[this.stack.length - 1];}empty() {return this.stack.length === 0;}
}

C++ Code

#include <stack>
using namespace std;class MyQueue {
private:stack<int> stack_in_;stack<int> stack_out_;void pour_to_stack_out_() {while (!stack_in_.empty()) {int top = stack_in_.top();stack_in_.pop();stack_out_.push(top);}};
public:/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {stack_in_.push(x);}/** Removes the element from in front of queue and returns that element. */int pop() {if (stack_out_.empty()) { pour_to_stack_out_();}int top = stack_out_.top();stack_out_.pop();return top;}/** Get the front element. */int peek() {if (stack_out_.empty()) { pour_to_stack_out_();}return stack_out_.top();}/** Returns whether the queue is empty. */bool empty() {return stack_in_.empty() && stack_out_.empty();}
};/*** Your MyQueue object will be instantiated and called as such:* MyQueue* obj = new MyQueue();* obj->push(x);* int param_2 = obj->pop();* int param_3 = obj->peek();* bool param_4 = obj->empty();*/

更多题解可以访问:https://github.com/suukii/91-days-algorithm

总结

以上就是本文所有内容了,希望能对你有所帮助,能够解决用栈实现队列问题。

如果你喜欢本文,也请务必点赞、收藏、评论、转发,这会对我有非常大的帮助。请我喝杯冰可乐也是极好的!

已完结,欢迎持续关注。下次见~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统架构设计师-第15章-面向服务架构设计理论与实践-软考学习笔记

面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA) 面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA&#xff09;是一种软件架构模式&#xff0c;它将应用程序的不同功能组织为一组可重用的、松耦合的、自治的服务&#xff0c;这些服务通…

在前端实现小铃铛上展示消息

点击铃铛显示如下消息框&#xff1a; 如果点击消息&#xff0c;可以实现消息从列表中移除,并从铃铛总数上进行扣减对应的已读消息数。 关于以上功能的实现方式&#xff1a; <!-- 铃铛位置 --><i class"el-icon-bell" click"showPopover true"&…

ubuntu启动报错error: proc_thermal_add, will cont

如题&#xff0c;ubuntu启动报错error: proc_thermal_add, will cont 截图如下&#xff1a; 困扰了我很久&#xff0c;差点就打算重装系统&#xff0c;准备放弃了&#xff0c;但是感谢国外的老哥&#xff0c;写了一篇非常详细的解决方案&#xff0c;我搬过来。 解决方案&#…

03-对象

对象 对象1.对象的创建字面量模式构造函数模式 2.对象的访问3.新增删除对象中的属性4.Object显示类型转换(强制类型转换)ECMAScript中可用的3种强制类型转换如下&#xff1a;Boolean(value)String(value)Number(value)Object类型到Boolean类型Object类型转String类型转换规则&a…

Redis通过复制rdb文件方式同步线上数据到本地以及提示:Can‘t handle RDB format version 9解决

场景 Redis的持久化机制-RDB方式和AOF方式&#xff1a; Redis的持久化机制-RDB方式和AOF方式_rdb 和ao-CSDN博客 Redis持久化机制导致服务自启动后恢复数据过长无法使用以及如何关闭&#xff1a; Redis持久化机制导致服务自启动后恢复数据过长无法使用以及如何关闭_霸道流氓…

mysql数据表设计

命名 mysql表名的命名规范为表名可以用 t_ 、tb_的前缀&#xff0c;或者是业务模块前缀。比如t_order。 有些项目也会使用 tt_、tm_、 ts_ 等前缀&#xff0c;根据项目的习惯命名就好了。 主键&#xff1a; AUTO_INCREMENT 表示自增&#xff0c;UNSIGNED 表示无符号&#xf…

【算法专题】双指针—盛最多水的容器

一、题目解析 分析这个题目不难得出一个容积公式 二、算法原理 解法一&#xff1a;暴力枚举&#xff08;超时&#xff09; 套用上述的容积公式&#xff0c;使用两个for循环来枚举出所有可能的情况&#xff0c;再挑出最大值即可&#xff0c;但是这种写法会超时&#xff0c;导致…

数据结构-初识泛型

写在前&#xff1a; 这一篇博客主要来初步的记录以下泛型的相关内容&#xff0c;内容比较琐碎&#xff0c;就不进行目录的整合&#xff0c;后续可能会对泛型这里进行系统性的梳理&#xff0c;此篇博客主要是对泛型有一个简单的认识与理解&#xff0c;需要知晓的内容。 当我调用…

2. 网络之网络编程

网络编程 文章目录 网络编程1. UDP1.1 DatagramSocket1.1.1 DatagramSocket 构造方法1.1.2 DatagramSocket 方法&#xff1a; 1.2 DatagramPacket1.2.1 DatagramPacket构造方法1.2.2 DaragramPacket方法1.2.3InetSocketAddress API 1.3 UDP回显服务器1.3.1 框架结构1.3.2 读取请…

将图像的锯齿状边缘变得平滑的方法

项目背景 使用PaddleSeg 192x192 模型分割出来的目标有锯齿状边缘&#xff0c;想通过传统算法将这种锯齿状边缘的变得平滑&#xff0c;虽然试了很过方法&#xff0c;但是效果还是不太理想 常用的集中方法 当使用分割算法&#xff08;如分水岭分割、阈值分割等&#xff09;分…

Docker:命令

Docker&#xff1a;命令 1. 创建MySQL的命令解读2. 基础命令3. 案例 查看DockerHub&#xff0c;拉取Nginx镜像&#xff0c;创建并运行Nginx容器4. 命令别名附录 1. 创建MySQL的命令解读 docker run :创建并运行一个容器&#xff0c;-d 是让容器在后台运行--name:给容器起一个名…

使用脚本整合指定文件/文件夹,执行定制化 ESLint 命令

背景 最近面对一个庞大的项目&#xff0c;但是只需要修改某个模块&#xff0c;每次都手搓命令太麻烦了&#xff0c;于是就想着能不能写个脚本来辅助处理这些事情。 解决方案 定制化一键 ESLint&#xff0c;执行文件下载地址&#xff1a; https://github.com/mazeyqian/go-g…

Python 自动化(十六)静态文件处理

准备工作 将不同day下的代码分目录管理&#xff0c;方便后续复习查阅 (testenv) [rootlocalhost projects]# ls day01 day02 (testenv) [rootlocalhost projects]# mkdir day03 (testenv) [rootlocalhost projects]# cd day03 (testenv) [rootlocalhost day03]# django-admi…

基于nodejs+vue啄木鸟便民维修网站设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

element-plus走马灯不显示

问题描述 依赖正确&#xff0c;代码用法正确&#xff0c;但是element-plu走马灯就是不显示&#xff01;&#xff01; <div class"content"><el-carousel height"150px" width"200px"><el-carousel-item v-for"item in 4&qu…

Android 默认关闭自动旋转屏幕功能

Android 默认关闭自动旋转屏幕功能 接到客户邮件想要默认关闭设备的自动旋转屏幕功能&#xff0c;具体修改参照如下&#xff1a; /vendor/mediatek/proprietary/packages/apps/SettingsProvider/res/values/defaults.xml - <bool name"def_accelerometer_rotati…

代码随想录图论并查集 | 第六天 1971. 寻找图中是否存在路径 684.冗余连接

代码随想录图论并查集 | 第六天 1971. 寻找图中是否存在路径 684.冗余连接 一、1971. 寻找图中是否存在路径 题目链接&#xff1a;https://leetcode.cn/problems/find-if-path-exists-in-graph/ 思路&#xff1a;典型并查集模板题。 class Solution {int[] father null;pub…

1、Flink基础概念

1、基础知识 &#xff08;1&#xff09;、数据流上的有状态计算 &#xff08;2&#xff09;、框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。 &#xff08;3&#xff09;、事件驱动型应用&#xff0c;有数据流就进行处理&#xff0c;无数据流就不…

【LeetCode热题100】两数之和 C++

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…

1 — NLP 的文本预处理技术

一、说明 在本文中&#xff0c;我们将讨论以下主题&#xff1a;1为什么文本预处理很重要&#xff1f;2 文本预处理技术。这个文对预处理做一个完整化、程序化处理&#xff0c;这对NLP处理项目中有很大参考性。 系列文章的后续&#xff1a; 2、NLP文本预处理技术&#xff1a;词干…