前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 上的一道题目

LeetCode 上的一道题目

作者头像
五分钟学算法
发布2020-06-28 15:46:52
4280
发布2020-06-28 15:46:52
举报
文章被收录于专栏:五分钟学算法五分钟学算法

今天分享的题目来源于 LeetCode 上的剑指 Offer 系列 面试题09. 用两个栈实现队列

题目链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

一、题目描述

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTaildeleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

示例 1:

代码语言:javascript
复制
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]

示例 2:

代码语言:javascript
复制
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]

提示:

  • 1 <= values <= 10000
  • 最多会对 appendTail、deleteHead 进行 10000 次调用

二、题目解析

实名吐槽这道题目的示例描述,我第一次真的没有看懂是啥意思。。。。

我用大白话来翻译一下 示例 2

代码语言:javascript
复制
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
这个表示每一次操作的集合数组
代码语言:javascript
复制
[[],[],[5],[2],[],[]]
这个表示每一次操作后对应的参数的集合数组
1、CQueue

首先初始化,没有参数,所以是 [],然后我们注意到 CQueue() 函数是没有返回值的,用 null 来表示(不要问我为什么用 null 表示。。。)

2、deleteHead

删除操作,没有参数,所以是 [],根据题意若队列中没有元素,deleteHead 操作返回 -1 ,所以输出值为 -1

3、appendTail

插入操作,有参数,此时是 5,并且 appendTail() 函数没有返回值的,用 null 来表示。

4、appendTail

插入操作,有参数,此时是 2,并且 appendTail() 函数没有返回值的,用 null 来表示。

5、deleteHead

删除操作,没有参数,所以是 [],此时队列中有元素,先进入的是 5,后进入的是 2,根据队列 先进先出 的性质,元素 5 出列,所以返回值是 5

6、deleteHead

删除操作,没有参数,所以是 [],此时队列中有元素,只有元素 2,所以返回值是 2

基本上看完上面的大白话翻译就可以理解题意,解决问题也不难了。

入队操作

如果是栈的插入操作,那我们可以把元素都先插入到 stack1 中,也就实现了队列的 入队操作

出队操作
  • 当 stack2 中不为空时,直接操作,此时在 stack2 中的栈顶元素是最先进入队列的元素,返回该元素即可;
  • 如果 stack2 为空且 stack1 也为空,返回 -1;
  • 如果 stack2 为空且 stack1 不为空,首先需要把 stack1 中的元素逐个弹出并压入到 stack2 中,然后返回 stack2 的栈顶元素即可。

示例

三、动画描述

四、图片描述

五、参考代码

代码语言:javascript
复制
class CQueue {

    LinkedList<Integer> stack1;
    LinkedList<Integer> stack2;

    public CQueue() {
        // 初始化 stack1 与 stack2
        stack1 = new LinkedList<Integer>();
        stack2 = new LinkedList<Integer>();
    }

    public void appendTail(int value) {
        // 直接将元素存放到 stack1 中
        stack1.addLast(value);
    }

    public int deleteHead() {
        // stack2 栈不为空,直接操作,返回 stack2 的栈顶元素
        if(!stack2.isEmpty()) {
           return stack2.removeLast(); 
        }
        // 走到这一步的时候,stack2 是为空的状态
        // 根据题意,当 stack1 为空时,直接返回 -1
        if(stack1.isEmpty()){
            return -1;   
        }
        // 将 stack1 中的元素依次倒序放入 stack2 中
        while(!stack1.isEmpty()){
            stack2.addLast(stack1.removeLast()); 
        }
        // 返回 stack2 的栈顶元素  
        return stack2.removeLast();
    }
}

六、复杂度分析

插入元素操作
  • 时间复杂度:O(N)。插入元素时,对于已有元素,每个元素都要弹出栈两次,压入栈两次,因此是线性时间复杂度。
  • 空间复杂度:O(N)。需要使用额外的空间存储已有元素。
删除元素操作
  • 时间复杂度:O(1)。判断元素个数和删除队列头部元素都使用常数时间。
  • 空间复杂度:O(1)。从第一个栈弹出一个元素,使用常数空间。

七、相关标签

  • 队列
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 五分钟学算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目描述
  • 二、题目解析
    • 1、CQueue
      • 2、deleteHead
        • 3、appendTail
          • 4、appendTail
            • 5、deleteHead
              • 6、deleteHead
                • 入队操作
                  • 出队操作
                  • 三、动画描述
                  • 四、图片描述
                  • 五、参考代码
                  • 六、复杂度分析
                    • 插入元素操作
                      • 删除元素操作
                      • 七、相关标签
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档