题目描述
难度:简单
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 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 次调用
分析
双栈实现队列,可以维护一个删除元素的栈 deleteStack 和一个添加元素的栈 appendStack;
添加元素时就正常往 appendStack 里面 push 元素,队列的头部一直在栈低,队列尾部一直在栈顶;
而删除元素时 删除的元素是从 appendStack 中倒腾到 deleteStack 的,试想一下,appendStack 中维护的一直是队头在栈底,队尾在栈顶,如果我们将appendStack 中的元素挨个 pop 出来,然后 push 进 deleteStack 中,那么 deleteStack 中的栈顶元素就是队头了,栈底元素就是队尾了;
然后再 pop 掉 deleteStack 的栈顶元素,就实现了队头元素删除的效果;
一旦 deleteStack 空了,就再从 appendStack 中取出所有的值就好了。
代码:
public class CQueue {
Stack<Integer> appendStack; // 添加元素的栈
Stack<Integer> deleteStack; // 删除元素的栈
public CQueue() {
appendStack = new Stack<>();
deleteStack = new Stack<>();
}
public void appendTail(int value) {
appendStack.push(value);
}
public int deleteHead() {
if(deleteStack.isEmpty()){
if(appendStack.isEmpty()){
return -1; // 两个栈都是空的就返回 -1
}else {
while (!appendStack.isEmpty()){
deleteStack.push(appendStack.pop()); // 删除元素的栈中没元素了 就去添加元素的栈中取元素
}
}
}
return deleteStack.pop(); // pop出的元素就是队头元素
}
}
总结
利用两个栈实现队列,其实稍微熟悉队列和栈的工作模式的话,写出来应该不难,如果需要更有效率的解法,leetcode的题解中有更好的解法,我这个就是存粹的用栈模仿队列。
岁月悠悠,衰微只及肌肤;热忱抛却,颓废必致灵魂