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

87 阅读2分钟

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

一、题目内容

image.png

二、解题方法

  • 栈的特点是先进后出,队列的特点是先进先出。根据它们的特点,如果将数据压入到一个栈中,当要弹出数据时,先将数据全部弹出,依次压入到另一个栈中,此时再从第二个栈弹出的数据就满足先进先出的特点。

  • 看下图,stack1作为压入数据的栈,当添加数据时,将数据压入stack1image.png

  • stack2作为弹出数据的栈,当要弹出数据时,如果stack2为空,就将stack1中的数据依次弹出压入到stack2中,再弹出stack2的栈顶数据; image.png

  • 如果不为空,直接弹出stack2的栈顶数据; image.png

  • 添加数据时,将数据直接压入stack1,弹出数据时,直接弹出stack2的栈顶数据,使用这两个值,实现了先添加的数据,会先被弹出,即用两个栈实现了队列; image.png

image.png

  • 数组倒序方法reverce():反转数组中元素的顺序

image.png

  • 数组切片方法slice(start,end):以新的数组对象,返回数组中被选中的元素。选择从给定的 start 参数开始的元素,并在给定的 end 参数处结束,但不包括。

image.png

  • 数组切片方法splice():向/从数组添加/删除项目,并返回删除的项目,会改变原始数组

image.png

  • 删除数组末尾元素方法pop():移除数组的最后一个元素,并返回该元素,会改变数组的长度

  • 题解代码如下:

var CQueue = function() {
    this.stack_in = [];
    this.stack_out = [];
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
    this.stack_in.push(value);
};

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function() {
    if (this.stack_out.length == 0){
        for(let i = this.stack_in.length-1;i>=0;i--){
            this.stack_out.push(this.stack_in[i])
        }
        this.stack_in = []
        if (this.stack_out.length == 0){
            return -1;
        }
    }
    delnum = this.stack_out[this.stack_out.length-1]
    this.stack_out.splice(this.stack_out.length-1)
    return delnum
};