持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
题目
用两个栈实现一个队列。队列声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入节点和在队列头部删除节点的能力。
解题思路
栈的特点都知道是"先进后出",题目要求是实现尾部插入和头部删除能力。因此需要解决如何用两个栈来实现一个"先进先出"队列功能。
举例分析队列插入和删除的过程:
删除的操作
- 先向stack1插入元素a,b,c,stack1中元素:{a,b,c}
- 若要对元素做删除操作,删除头部元素a。栈是"先进后出",a元素在栈的栈底。
- 将stack1中的元素依次弹出压入stack2,stack2中元素:{c,b,a}
- 弹出stack2栈顶元素就删除了元素a
插入的操作
- 若要插入元素,若之前是做过删除操作就需要将stack2中的元素都压入到stack1中保证元素排序是正向。
- 然后再向stack1中插入新元素即可。
- 如果元素都在stack1中了,直接插入新元素。
Deque<Integer> stack1; // +队列
Deque<Integer> stack2; // -队列
public CQueue() {
stack1 = new ArrayDeque<Integer>();
stack2 = new ArrayDeque<Integer>();
}
public void appendTail(int value) {
stack1.push(value); // 添加
}
public int deleteHead() {
if (stack2.isEmpty()) {
if (stack1.isEmpty()) {
return -1;
}
in2out(); // 转移
}
return stack2.pop(); // 删除
}
private void in2out() {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
PS: deque容器为一个给定类型的元素进行线性处理,像向量一样,它能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它又与vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列。
总结
其实再想象一下两个栈是镜像的两个桶,输入都是往stack1进行,删除都是在stack2进行。
当需要进行添加操作时,将元素都移动到stack1中做添加操作;当需要进行删除操作时,将元素都移动到stack2中做删除操作。