题目
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 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 次调用
解题思路
解法一:
创建两个栈,一个为主,另一个为辅。根据队列特性,需要将新插入的元素放在主栈底部,而主栈顶部则是需要弹出的元素。这就需要用到辅助栈,具体做法就是两个栈中的元素相互倒腾,当新插入一个元素时,将主栈中的全部元素依次弹出并存入辅助栈中,然后插入新元素,最后再将辅助栈中的全部元素依次弹出并存入主栈中,这样就保证了主栈底部元素是始终新插入的元素,而其余元素的顺序也和插入新元素之前保持一致。
此外可以用一个变量维护队列的元素个数,用于判断队列是否为空。
复杂度分析:
插入元素:
时间复杂度:O(n)。插入元素时,对于已有元素,每个元素都要弹出栈两次,压入栈两次,因此是线性时间复杂度。
空间复杂度:O(n)。需要使用额外的空间存储已有元素。
删除元素:
时间复杂度:O(1)。判断元素个数和删除队列头部元素都使用常数时间。
空间复杂度:O(1)。从第一个栈弹出一个元素,使用常数空间。
解法二:
题目只要求实现 加入队尾appendTail() 和 删除队首deleteHead() 两个函数的正常工作,并未要求元素具体存放于哪个栈中。因此我们可以设计栈 A 用于加入队尾操作,栈 B 用于将元素倒序,从而实现删除队首元素。
1)加入队尾 appendTail()函数: 将数字 val 加入栈 A 即可。
2)删除队首deleteHead()函数: 有以下三种情况。
当栈 B 不为空: B中仍有已完成倒序的元素,因此直接返回 B 的栈顶元素。
否则,当 A 为空: 即两个栈都为空,无元素,因此返回 -1 。
否则: 将栈 A 元素全部转移至栈 B 中,实现元素倒序,并返回栈 B 的栈顶元素。
类似题目 225.用队列实现栈
代码
解法一:
Python代码如下:
class CQueue:
def __init__(self):
self.stack = []
self.supstack = []
self.size = 0
def appendTail(self, value: int) -> None:
while self.stack:
self.supstack.append(self.stack.pop())
self.stack.append(value)
while self.supstack:
self.stack.append(self.supstack.pop())
self.size += 1
def deleteHead(self) -> int:
if self.size == 0:
return -1
self.size -= 1
return self.stack.pop()
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
Java代码如下:
class CQueue {
Stack<Integer> stack;
Stack<Integer> supstack;
int size;
public CQueue() {
stack = new Stack<Integer>();
supstack = new Stack<Integer>();
size = 0;
}
public void appendTail(int value) {
while(!stack.isEmpty()){
supstack.add(stack.pop());
}
stack.add(value);
while(!supstack.isEmpty()){
stack.add(supstack.pop());
}
size++;
}
public int deleteHead() {
if(size==0){
return -1;
}
size--;
return stack.pop();
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/
解法二:
Python代码如下:
class CQueue:
def __init__(self):
self.stack = []
self.supstack = []
def appendTail(self, value: int) -> None:
self.stack.append(value)
def deleteHead(self) -> int:
# if self.supstack:
# return self.supstack.pop()
# if not self.stack:
# return -1
# while self.stack:
# self.supstack.append(self.stack.pop())
# return self.supstack.pop()
# 以下参考剑指offer写法
if not self.supstack:
while self.stack:
self.supstack.append(self.stack.pop())
if not self.supstack:
return -1
return self.supstack.pop()
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
Java代码如下:
class CQueue {
Stack<Integer> stack;
Stack<Integer> supstack;
public CQueue() {
stack = new Stack<Integer>();
supstack = new Stack<Integer>();
}
public void appendTail(int value) {
stack.add(value);
}
public int deleteHead() {
// if(!supstack.isEmpty()){
// return supstack.pop();
// }
// if(stack.isEmpty()){
// return -1;
// }
// while(!stack.isEmpty()){
// supstack.add(stack.pop());
// }
// return supstack.pop();
// 以下参考剑指offer写法
if(supstack.isEmpty()){
while(!stack.isEmpty()){
supstack.add(stack.pop());
}
}
if(supstack.isEmpty()){
return -1;
}
return supstack.pop();
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/