三种方法实现后入先出的栈---leetcode题解225

2023-05-16

声明:问题描述来源于leetcode

一、问题描述:

用队列实现栈

CategoryDifficultyLikesDislikes
algorithmsEasy (67.64%)480-
Tags

stack | design

Companies

bloomberg

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

实现 MyStack 类:

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

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsizeis 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
  • 最多调用100pushpoptopempty
  • 每次调用 poptop 都保证栈不为空

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


Discussion | Solution

二、题解1:通过链表实现堆栈

通过list作为容器,直接见招拆招,要什么方法就通过list来实现什么方法,xin麒觉得应该还是比较容易懂的。

xin麒的思路:

  • 首先定义List类型的成员变量list
  • 1、构造方法:初始化list
  • void push(int x):通过分析堆栈的push方法的特点:将元素添加到末尾
    • 于是直接调用list的add方法即可
  • int pop():因为堆栈的push方法是移除并返回栈顶元素
    • 于是直接通过list的remove(int index)方法传入末元素的索引即可提取所要求的元素
  • int top():和pop方法类似,不过换成list的get(int index)方法即可
  • boolean empty():通过三目运算直接返回list.size() == 0的运行结果即可
class MyStack {
    List<Integer> list;
    public MyStack() {
        list = new LinkedList<>();
    }

    public void push(int x) {
        list.add(x);
    }

    public int pop() {
        if (list.size() != 0){
            return list.remove(list.size() - 1);
        }
        return 0;
    }

    public int top() {
        if (list.size() != 0){
            return list.get(list.size() - 1);
        }
        return 0;
    }

    public boolean empty() {
        return list.size() == 0;
    }
}

/**
 * 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();
 */

运行:

在这里插入图片描述

三、题解2:通过两个队列实现堆栈

思考过程:

要通过两个队列实现堆栈,那么就要比较队列和堆栈的区别:

  • 共同点:push方法是比较类似的比较好办,直接使用add()方法传入参数即可

    ​ empty()方法也是比较容易的,因为直接判断队列是否为空即可

  • 不同点:pop方法中在堆栈的功能是:移除并返回栈顶元素;

    ​ 在队列的功能是:移除并返回队列元素。

(1)、int pop():

top方法和pop方法类似,于是难点便是如何处理pop方法了:

那么如果将第一个队列的元素一个一个往第二个队列放会有什么效果呢?

在这个过程的细节是:第一个队列的首元素不断通过pop方法添加到第二个队列里面,其中第二个队列是使用push来接收。

于是xin麒想到可以在第一个队列不断调用pop方法时,等到第一个队列只剩下1个元素时,不就是所需提取的元素了吗?因此问题就基本解决了,当第一个队列的剩下1个元素时,直接提取该元素,后面再将这个元素返回即可。

然后为了配合push方法的使用(因为此时如果再给堆栈添加元素,那么就要添加到第二个队列里面),于是将第一个队列指向第二个队列,第二个队列就重开吧。

(2)、boolean empty():

于是可以把第一个队列称为主队列mainQueue,第二个队列称为副本队列subordinateQueue。因此empty方法直接判断主队列是否为空即可。

(3)、int top():

top方法和pop方法比较类似,把提取的元素添加追加到副本队列即可。

class MyStack {
    Queue<Integer> mainQueue;
    Queue<Integer> subordinateQueue;

    public MyStack() {
        mainQueue = new LinkedList<>();
        subordinateQueue = new LinkedList<>();
    }

    public void push(int x) {
        mainQueue.add(x);
    }

    public int pop() {
        if (!mainQueue.isEmpty()){
            while (mainQueue.size() != 1){
                subordinateQueue.add(mainQueue.poll());
            }
            int result = mainQueue.poll();
            mainQueue = subordinateQueue;
            subordinateQueue = new LinkedList<>();
            return result;
        }
        return 0;
    }

    public int top() {
        if (!mainQueue.isEmpty()) {
            while (mainQueue.size() != 1) {
                subordinateQueue.add(mainQueue.poll());
            }
            int result = mainQueue.peek();
            subordinateQueue.add(result);
            mainQueue = subordinateQueue;
            subordinateQueue = new LinkedList<>();
            return result;
        }
        return 0;
    }

    public boolean empty() {

        return mainQueue.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();
 */

运行:
在这里插入图片描述

简化:

因为有些代码可以复合的,xin麒就把它们封装在一个函数了,这样看起来比较简洁些。

class MyStack {
    Queue<Integer> mainQueue;
    Queue<Integer> subordinateQueue;

    public MyStack() {
        mainQueue = new LinkedList<>();
        subordinateQueue = new LinkedList<>();
    }

    public void push(int x) {
        mainQueue.add(x);
    }
    
    public int xinDo(){
        int result = 0;
        if (!mainQueue.isEmpty()){
            while (mainQueue.size() != 1){
                subordinateQueue.add(mainQueue.poll());
            }
            result = mainQueue.poll();
            mainQueue = subordinateQueue;
            subordinateQueue = new LinkedList<>();
        }
        return result;
    }

    public int pop() {
        return xinDo();
    }

    public int top() {
        int result = xinDo();
        mainQueue.add(result);
        return result;
    }

    public boolean empty() {

        return mainQueue.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();
 */

四、题解3:一个队列实现堆栈:

思路:

1、push方法不变,依然是使用list的add方法;

2(重点)、不断将队列首元素往末尾元素追加,同时移除该首元素,直到首元素为栈顶元素时便提取该元素作为返回值。

pop方法和top方法类似,稍做处理即可;

empty方法判断队列是否为空即可。

int pop():

思考过程:

  • 不断将队列首元素往尾部扔的过程中如何知道轮到栈顶元素了呢?这个问题很重要,因此可以通过size()得到变量size来处理扔的过程,使用变量result来保存要返回的结果。
  • 如果queue为非空,那么将队列的首元素扔出来(poll),同时扔进(add)该队列的尾部,在一直扔的过程中,(--size >= 1)作为循环退出的条件。当条件为false时退出循环,并且此时的首元素即为所要返回的元素,于是在队列里面移除该元素,存放到result里面。

int top:

  • 如果队列非空,那么这里可以直接调用pop()并且以result接收,因为pop方法已经将队列的元素删除了,于是再add回来即可。
class MyStack {
    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<>();
    }

    public void push(int x) {
        queue.add(x);
    }

    public int pop() {
        int size = queue.size();

        int result = 0;
        if (size != 0){
            while (--size >= 1){
                queue.add(queue.poll());
            }
            result = queue.poll();
        }
        return result;
    }

    public int top() {
        if (queue.isEmpty()){
            return 0;
        }
        int result = pop();
        queue.add(result);
        return result;
    }

    public boolean empty() {
        return queue.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();
 */

运行:

在这里插入图片描述

end

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三种方法实现后入先出的栈---leetcode题解225 的相关文章

  • 如何设定Listview表头的背景色

    1 设定Listview的OwnerDraw属性为True 2 在Listview的DrawColumnHeader的事件中添加如下代码 xff1a e Graphics FillRectangle Brushes LightBlue e
  • DevExpress DataGrid Auto Filter Row 单元格实现单击全选

    如下图 xff0c 为提高工作效率 xff0c 要求单击时可以全选里面值 xff1a 研究了半天 xff0c 没有找到合适的事件 xff0c 后来还是在一个朋友的指点下得己实现 xff0c 代码如下 xff1a lt summary gt
  • MySQL 设定定时任务

    1 打开计划事件开关 SET GLOBAL event scheduler 61 ON 2 查看计划事件是否打开 SELECT 64 64 event scheduler 3 设定计划事件 CREATE EVENT IF NOT EXIST

随机推荐

  • MySQL 建视图时使用Union 报错1064

    SQL语句可以正常执行 xff0c 但创建视图时报错1064 xff0c 经多方资料查找 xff0c 格式调整 xff0c 原因竟然是不能用 xff08 xff09 xff0c 即创建视时SQL语句外围不能用 xff08 xff09 xff
  • C# winform ListView实现表示点击排序

    自用的小工具要实现这个功能 xff0c 网上找了些代码 xff0c 加工一下 xff0c 以下步骤 xff0c 亲测可用 菜鸟可一步步跟着来 xff0c 老鸟绕道啦 1 新建一个排序类 xff0c 代码如下 xff1a public cla
  • Oracle VM VirtualBox各种显示模式切换 热键

    初用VirtualBox 几个显示切换快捷键还是要记一下的 Right Ctrl 43 F 切换到全屏模式 Right Ctrl 43 L 切换到无缝模式 Right Ctrl 43 C 切换到比例模式 Right Ctrl 43 Home
  • PostgreSQL11.2 configure卡住 checking for DocBook XML V4.2

    在PG11 2的数据库编译过程中 xff0c 卡在了 checking for DocBook XML V4 2 xff0c 不动 xff0c 需要安装docbook才可以 需要安装 xff1a yum install docbook dt
  • 广东中山电信DNS地址 (铁通/网通)

    202 96 128 166 202 96 128 86 202 96 134 133 总忘 先记在这儿吧 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • SMARTFORM A5单据打印(自定义纸张/针式打印机)格式问题

    一张A5横放的单据 xff0c 做SmartForm时很自然的选择了DINA5 xff0c 然后横放 xff0c 测试的时候一直用激光打印机 xff0c 感觉挺正常 实际使用时发现异常 xff0c 不得己自己定义了一个A5横放的自定纸型 x
  • 检查c#代码内存泄露工具-CLR Profiler

    转自 xff1a http blog csdn net hualusiyu article details 8166450 大家都知道 net 有一套自己的内存 xff08 垃圾 xff09 回收机制 xff0c 除非有一些数据 xff08
  • 在SAP中创建并运用条形码

    原文地址 xff1a http blog chinaunix net u2 64924 showart 715473 html 在 SAP 中创建并运用条形码的过程如下 xff1a 1 以 T CODE xff1a SE73 进行后如图 x
  • 常用数据库建模工具

    收藏 xff1a http www oschina net project tag 83 db model Intellij下mybatis插件 MyBatisCodeHelper 国产 MyBatisCodeHelper 是 Intell
  • surface pro 4 发热抖屏的解决方法

    用了三年 xff0c 同样的问题 xff0c 以下方法试验中 以牺牲性能方法来降低发热 xff0c 从而避免抖屏 xff0c 不得已而为之 https tieba baidu com p 5598171696 red tag 61 1289
  • 关于物化视图增量刷新报ORA-12018 问题的解决方案

    由于表之前采用的是全量刷新方式进行刷新 xff0c 但是因为表的数据量越来越大 xff0c 全量刷新的时候偶尔会出现失败的情况 xff0c 因为同一个时点刷新的任务比较多 xff0c 回滚段被占满了之后会出现报错 xff0c 所以急需要解决
  • c语言中四种简单的数组排序

    前言 本文介绍了几种c语言中对乱序数组的排序方式 具体的内容有 xff1a 插入排序 xff1b 冒泡排序 xff1b 选择排序 xff1b 希尔排序 xff1b 具体内容详见下文 一 插入排序 1 思路 首先假设数组的的前n位元素是有序的
  • 网桥的功能和分类

    br lan 61 lan 网桥 将WLAN和LAN 交换机 绑定为一个虚拟接口 连接两个局域网 xff0c 负责数据的中继和转发 交换机的前生 集线器 xff08 Hub xff09 是中继器的一种形式 xff0c 区别在于集线器能够提供
  • Java简介

    今天开始学习Java啦 xff0c 每天进步一点点 xff01 1 Java语言发展史 Java语言是美国Sun Stanford University Network 公司在1995年推出的计算机语言 xff0c java之父 xff1a
  • win10上WSL+vscode+xserver配置linux图形化程序开发环境

    受够了双系统来回切换 xff0c 尝试了一下wsl配置linux环境 xff08 个人习惯在linux上敲代码 xff09 xff0c 由于需求图形化 xff0c 又弄了xserver 没有装linux图形界面 WSL 安装按着官方的文档来
  • 02.Ubuntu 18.04安装KVM

    02 Ubuntu 18 04安装KVM 1 检查是否支持虚拟化 span class token function egrep span span class token parameter variable c span span cl
  • maven 打包缺失 resources 目录下的 jar 包,警告 jar should not point at files within the project directory

    报错如下 INFO Scanning for projects WARNING WARNING Some problems were encountered while building the effective model for co
  • Linux 下利用trash替换rm

    前言 rmtrash 是linux和mac下命令行版本rm的回收站 xff0c 安装后对用户透明 xff0c 符合正常使用rm的习惯 支持rm fr file哦 xff0c 有了他再也不怕rm时候手颤抖了 能自动拒绝 rm fr 哦 安装
  • 【异常】记一次前端因资源无法加载导致白屏异常问题

    一 背景 自从运维同事强烈要求前端的环境要使用多套的 xff0c 参考文章 项目 参考若依的前端框架去多环境 于是一番捣鼓与改造之后 xff0c 看似已经顺利了 但运维说 xff0c 前端还是有问题 xff0c 需要他帮我改下 xff0c
  • 三种方法实现后入先出的栈---leetcode题解225

    声明 xff1a 问题描述来源于leetcode 一 问题描述 xff1a 用队列实现栈 CategoryDifficultyLikesDislikesalgorithmsEasy 67 64 480 Tags stack design C