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

本文通过详细解析字节跳动面试题——用两个栈实现队列,探讨如何利用栈的特性实现队列的先进先出功能。通过示例及代码实现,阐述了如何在栈中进行数据的进出操作,以达到队列的效果。同时,展示了具体的代码实现过程,帮助理解数据结构在实际问题中的应用。

剑指Offer 09:用两个栈实现队列(字节跳动面试题目)

题干

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

示例1:

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

示例2:

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

提示:

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

看了题干猛一下有点懵,原来我不是一个人hhh
在这里插入图片描述

在这里插入图片描述

1、CQueue

首先初始化,没有参数,所以是 [],然后我们注意到 CQueue() 函数是没有返回值的,用 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 。

怎么想

栈是一种先进后出的数据结构,队列却是一种先进先出的数据结构。

题目要求我们使用两个栈来实现一个队列,首先一点我们可以确定的是一开始往队列中 append 的数据肯定是存储在一个栈中的。

也就是说先 append 的数据都是存储在栈的栈底,换句话说,队头的元素一开始肯定是存储在一个栈中的栈底。

如果我们现在想删除队头的元素的话,也就是说我们要删除的是一个栈底的元素,肯定是直接删除不到的。

因为我们有两个栈,所以我们可以将 append 进来的数据从栈中 pop 出来,然后 push 到另一个栈中,这样之前栈底的元素就变为另一个栈顶的元素了,然后 pop 掉栈顶元素就可以了。

图片实现

  • 首先先进栈 appendTail
  • 因为要满足双栈实现队列的先进先出,所以数字1要先出栈,此时利用另一个栈,将第一个栈内元素进入第二个栈,进而使得元素1在第二个栈顶然后顺利出栈(deleteHead)
  • 中间若有进栈元素,依然遵循先进先出原则,即先将7,9先入栈,然后将10再入栈,进而实现双栈队列


    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

代码实现

class CQueue {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;
    public CQueue() {
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }

    public void appendTail(int value) {
        while (!stack2.isEmpty()) {
            stack1.push(stack2.pop());
        }
        stack1.push(value);
    }

    public int deleteHead() {
        while (!stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
        if (stack2.isEmpty()) {
            return -1;
        }
        return stack2.pop();
    }
}



结果如下

在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值