一、题目
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail
和 deleteHead
,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,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
- • 最多会对
appendTail
、deleteHead
进行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();
}
}