学习笔记:剑指 Offer 09. 用两个栈实现队列

227 阅读3分钟

题目描述

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

题目示例一

输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]

题目示例二

输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]

题目解析

这个题目可以理解为使用栈的特性(FILO)实现队列的特性(FIFO)

接下来说一下题目中给出的示例

示例一:

输入的 ["CQueue","appendTail","deleteHead","deleteHead"] 表示要执行的操作,根据数组中的的单词可以理解为 第一步是创建一个队列CQueue, 接下来执行appendTail操作,然后再执行两遍deleteHead操作。 第二行中的[[],[],[5],[2],[],[]]这段代码是对应上面 ["CQueue","appendTail","deleteHead","deleteHead"]执行操作所需要的参数(按照顺序一一对应)。从示例代码中可以看出,这里有个规则:如果是创建和添加操作,都返回null,如果是删除操作,队列内有数据的话,返回删除了的数据,队列为空的话返回-1,因此可以得出下面的步骤。

  • 第一步 执行CQueue操作,所需要参数为[], 返回null
  • 第二步 执行appendTail操作,所需要的参数为3, 返回null
  • 第三步 执行deleteHead操作,所需要的参数为[] 返回3
  • 第四步 执行deleteHead操作,所需要的参数为[], 返回-1

示例二

这个示例代码逻辑跟示例一代码基本差不多,唯一需要注意的是队列的特性,要遵循先进先出的原则,下面直接写出步骤。

  • 第一步 执行CQueue操作,所需要参数为[], 返回null
  • 第二步 执行deleteHead操作,所需参数为[], 此时队列为空,没有可以删除的元素,所以返回-1
  • 第三步 执行appendTail操作, 所需要的参数为5, 向队列中添加元素5,返回null
  • 第四步 执行appendTail操作,所需要的参数为2,向对列中添加元素2,返回null
  • 第五步 执行deleteHead操作,所需要的参数为[],删除头部元素,根据先进先出原则,元素5先于元素2入队列的,所以此时返回的应该是5
  • 第六步 执行deleteHead操作,所需要的参数为[],此时队列中的元素只有2了,因此将此元素执行出队列的操作,返回该元素2

代码实现

通过对题目和代码示例的分析,了解了此题所要考察的内容之后,接下来使用代码来完成这个题目

// 题干中指定了使用两个栈来实现一个队列,这里声明一个构造函数CQueue
// 定义两个属性,对应的值都为空数组
const CQueue = function () {
    // stack1用来进行压栈操作
    this.stack1 = [];
    // stack2用来出栈操作
    this.stack2 = [];
}

// 在CQueue构造函数的原型链上定义appendTail方法,执行该方法的时候,
// 将传入的参数value添加到stack1栈中
CQueue.prototype.appendTail = function(value) {
    this.stack1.push(value)
}

// 在CQueue构造函数的原型链上定义deleteHead方法,执行该方法的时候,
// 需要做下面的判断

CQueue.prototype.deleteHead = function() {
    if (this.stack2.length === 0) {
        // 如果stack2内容为空,循环stack1,将其内容全部压入stack2中,
        // 这里需要注意的是,由于我们是在模拟实现一个队列
        // 而队列的特性是FIFO,所以为了保证顺序,stack1出栈操作需要用pop方法
        while(this.stack1.length > 0) {
            this.stack2.push(this.stack1.pop())
        }
    }
    // 判断stack2的内容不为空,则执行stack2的出栈操作(从栈底出栈)
    // 否则 返回 -1
    if (this.stack2.length > 0) {
        return this.stack2.pop()
    } else {
        return -1
    }
}

题目来源

剑指 Offer 09. 用两个栈实现队列