【面试题09 用两个栈实现队列】
难度: 简单
限制: 1 <= values <= 10000,最多会对 appendTail、deleteHead 进行 10000 次调用
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
Leetcode题目对应位置: 面试题09:用两个栈实现队列
复习:
- 队列的特性是 “先进先出”,即最先入队的元素也先出队,就像排队买票一样
- 栈的特性是 “后进先出”,即最后入栈的元素最先出栈
原题:双栈实现队列
题目要求用两个栈来实现队列,主要是为了了解一下两种数据结构的区别(不然的话我会直接 stack.append(value)
& return stack[0]
🤣)
由于队列和栈的特性不同,所以可以用两个栈实现元素的倒序,从而维护队列的特性。
每次入队列的元素直接入栈 stack1
,如果要出队列,就将 stack1
的元素依次出栈并入栈到 stack2
,此时 stack2
的栈顶元素就是要出队列的元素。
注意一点,出队列后并不需要将 stack2
的元素再放回 stack1
,因为接下来要出队列的数就按顺序排列在 stack2
的栈顶到栈底,入队列照常入 stack1
,出队列从 stack2
栈顶拿,只有当 stack2
空了才从 stack1
倾倒所有的数。这样应该是双栈法效率最高的一种方案了。
时间复杂度:O(n),入队列为 O(1),出队列为 O(n)
空间复杂度:O(n)
Python 代码:
class CQueue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def appendTail(self, value: int) -> None:
self.stack1.append(value)
def deleteHead(self) -> int:
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
if self.stack2:
return self.stack2.pop()
else: return -1
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
C++ 代码:
class CQueue {
stack<int> stack1;
stack<int> stack2;
public:
CQueue() {}
void appendTail(int value) {
stack1.push(value);
}
int deleteHead() {
if (stack2.empty())
{
while (!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
int res = -1;
if (!stack2.empty())
{
res = stack2.top();
stack2.pop();
}
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
扩展:双队列实现栈
定义两个空队列,均只能从尾部放入元素、从头部取出元素。要实现栈,可以遵循一下思路:
1)初始时队列均为空,要入栈则任选一个队列放入元素;
2)每次入栈时都将元素放在不为空的那个队列;
3)当要出栈时,将不为空的队列中的元素依次出队列并放入另一个为空的队列,当只剩下一个元素时停止,此时该元素就是要出栈的元素,直接出栈不放入队列。
class CStack:
def __init__(self):
self.queue1 = []
self.queue2 = []
def append(self, value: int) -> None:
if self.queue1: self.queue1.append(value)
else: self.queue2.append(value)
def delete(self) -> int:
i = 0
if self.queue1:
while i < len(self.queue1)-1:
self.queue2.append(self.queue1[i])
i += 1
res = self.queue1[i]
self.queue1.clear()
return res
else:
while i < len(self.queue2)-1:
self.queue1.append(self.queue2[i])
i += 1
res = self.queue2[i]
self.queue2.clear()
return res
参考资料:
LeetCode 面试题09:用两个栈实现队列