剑指 Offer 09. 用两个栈实现队列
题目描述
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”]。1
[[],[3],[],[]]2
输出:[null,null,3,-1]
示例 2:
输入:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]1
[[],[],[5],[2],[],[]]2
输出:[null,-1,null,null,5,2]
难度:简单🖱题目链接
解题思路
目的是解题而不是去用数据结构的思想
方法一(ArrayList实现)
由于需要实现的函数功能为在尾部插入、头部删除,最简单的方法可以使用ArrayList集合,由于其动态的性质可以采用add()方法与remove()方法实现题干要求
上代码!
class CQueue {
ArrayList<Integer> queue = new ArrayList<>();
public CQueue() {
queue.clear();
}
public void appendTail(int value) {
queue.add(value);
}
public int deleteHead() {
if (queue.size()==0) {
return -1;
}else{
return queue.remove(0);
}
}
}
CQueue():将方法外queue清空(完成初始化)
appendTail():ArrayList提供的add()方法为在原集合后插入新的元素,故无需修改直接调用即可
deleteHead():第一步先判断queue是否为空,若空则返回-1,若非空则用remove()方法删除第0个元素,即头元素
方法二(Deque实现)
定义主栈与辅助栈,主栈用来存放插入的数据,辅助栈用来将主栈数据逆序存放,以达到弹出元素为队首元素。
注:为方便理解队列和栈,可以把栈理解为把子弹压入弹匣,最先进入弹匣(栈)的子弹(元素)最后才会弹出,最后进入弹匣(栈)的子弹(元素)最先被弹出,此为LIFO(Last in first out)。队列,就如字面意思一样,好比排队做核酸,排在最前面的人做完核酸就可以离队,而想要做核酸就要从队尾开始排,等前面所有人做完核酸就可以轮到自己,此为(First in first out)
class CQueue {
Deque<Integer> inStack;
Deque<Integer> outStack;
public CQueue() {
inStack=new ArrayDeque<>();
outStack=new ArrayDeque<>();
}
public void appendTail(int value) {
inStack.push(value);
}
public int deleteHead() {
if (outStack.isEmpty()) {
if (inStack.isEmpty()) {
return -1;
}
in2out();
}
return outStack.poll();
}
private void in2out(){
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
}
}
in2out()方法为将主栈元素全部弹出并压入辅助栈,即可实现主栈元素逆序存放,达到FIFO(First in first out)的目的。