图解LeetCode——剑指 Offer 09. 用两个栈实现队列(难度:简单)

2023-05-10 13:20:08 浏览数 (1)

一、题目

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

二、示例

示例 1:

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

示例 2:

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

提示:

  • 1 <= values <= 10000
  • • 最多会对 appendTaildeleteHead 进行 10000 次调用

三、解题思路

因为题目要求,通过2个堆栈的数据结构来实现1个队列的数据结构,那么要解答这道题,我们就需要明白栈和队列的相关特性:

】对于元素采用 先进后出 的操作方式。 【队列】对于元素采用 先进先出 的操作方式。

既然我们了解了栈和队列对于元素维护的操作方式,那么我们其实就可以利用两个栈的先进先出特性模拟出一个队列。即:

  • stackIn】只负责 添加元素 操作的栈;
  • stackOut】只负责 获取 / 移除 操作的栈;

那么当添加元素的时候,只需要向栈stackIn添加即可;那么当调用获取元素的时候,我们只需要从stackOut中弹出栈顶元素即可。

那么如果stackOut中为空了怎么办呢?我们会尝试将当前stackIn中所有的元素移动到stackOut中,然后再执行弹出栈顶元素操作。但是,如果stackIn中也为空的话,我们就直接返回-1即可。具体操作逻辑请见下图所示:

最后需要说明一下,就是在题解中,为了提升执行速度,我们没有采用Stack类,而是采用Deque(双向队列)类中的addLast(...)removeLast()方法来模拟栈结构。

四、代码实现

代码语言:javascript复制
class CQueue {
    private Deque<Integer> stackIn, stackOut;
    public CQueue() {
        stackIn = new ArrayDeque<>();
        stackOut = new ArrayDeque();
    }

    public void appendTail(int value) {
        stackIn.addLast(value);
    }

    public int deleteHead() {
        if (!stackOut.isEmpty()) return stackOut.removeLast();
        if (stackIn.isEmpty()) return -1;
        while (!stackIn.isEmpty()) 
            stackOut.addLast(stackIn.removeLast());
        return stackOut.removeLast();
    }
}

0 人点赞