【算法实战之力扣刷题】用栈实现队列

59 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

题目描述:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出: [null, null, null, 1, 1, false]

解题思路:

方法一:双栈

  1. 理解栈和队列

    栈是一种先进后出的数据结构,栈中元素从栈顶(top)压入,也从栈顶弹出

    队列是一种先进先出的数据结构,队列中的元素都从队尾(rear)入队,队首(front)出队。

  2. 模拟队列的行为,需要用到两个栈一个为输入栈,一个为输出栈

  3. 模拟队列入队(push)的时候,只要数据压入输入栈就好。模拟队列出队(pop)的时候,输出栈如果没有内容,就把输入栈全部数据依次弹出并压入(输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序),再从栈顶弹出栈顶数据;如果输出栈存在内容,则栈顶数据直接弹出就可以了。最后如果输入栈和输出栈都为空的话,说明模拟的队列为空了。

var MyQueue = function() {
    // 定义两个栈
    this.inStack = [];
    this.outStack = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
    //把数据加入输入栈
    this.inStack.push(x)
};

/**
 * @return {number}
 */
MyQueue.prototype.pop = function() {
    const size = this.outStack.length;
    // 如果输出栈有数据,就直接弹出栈顶元素(相当于删除数组最后一个元素)
    if(size){
        return this.outStack.pop();
    }
    // 如果输出栈没有数据,输入栈存在数据时,将输入栈的数据一一加入输出栈中
    while(this.inStack.length){
        this.outStack.push(this.inStack.pop());
    }
    return this.outStack.pop();
};

/**
 * @return {number}
 */
MyQueue.prototype.peek = function() {
    const x = this.pop(); // 获得队头的数据
    //因为执行了一次删除输入栈栈顶元素,所以需要把该元素加回去
    this.outStack.push(x)
    return x
};

/**
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
    return !this.inStack.length && !this.outStack.length
};

方法二: 数组、es6扩展运算符、数组的解构赋值

首先定义一个数组(模拟队列),通过数组的push()方法可以实现将元素 x 加到队列的末尾;运用es6的扩展运算符和数组的解构赋值,得到数组的第一个和后面的元素(组成一个数组newArr),在队列的pop()方法中返回数组的第一个元素,并更新数组为newArr(没有了数组的第一个元素,相当于删除了)

var MyQueue = function() {
    //定义一个数组
    this.arr = [];
};

MyQueue.prototype.push = function(x) {
    this.arr.push(x); //在数组末尾加入元素
};

MyQueue.prototype.pop = function() {
    let [a, ...newArr] = this.arr;
    this.arr = newArr;
    return a;
};

MyQueue.prototype.peek = function() {
    return this.arr[0];  //返回数组第一个元素
};

MyQueue.prototype.empty = function() {
    return !this.arr.length;
};

image.png