大家好,我是木川
一、题目描述
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x)将元素 x 压入栈顶。int pop()移除并返回栈顶元素。int top()返回栈顶元素。boolean empty()如果栈是空的,返回true;否则,返回false。
注意:
你只能使用队列的基本操作 —— 也就是
push to back、peek/pop from front、size和is empty这些操作。你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False提示:
1 <= x <= 9最多调用
100次push、pop、top和empty每次调用
pop和top都保证栈不为空
进阶:你能否仅用一个队列来实现栈。
二、题解
一)两个队列
思路:
1、queue1 存储栈内的元素,queue2 作为入栈操作的辅助队列
2、入栈操作:将元素入队列 queue2,然后将 queue1 中的元素出队列入 queue2,再将 queue1 和 queue2 交换,则 queue1 的元素为栈内的元素,queue2 为空
3、出栈操作:只要 从 queue1 出栈即可
代码:
type MyStack struct {
queue1, queue2 []int
}
func Constructor() MyStack {
return MyStack{}
}
func (this *MyStack) Push(x int) {
// 队列2 存储最新的元素
this.queue2 = append(this.queue2, x)
// 将 队列1 的元素依次放入 队列2
for len(this.queue1) > 0 {
this.queue2 = append(this.queue2, this.queue1[0])
this.queue1 = this.queue1[1:]
}
// 交换队列1 和 队列2
this.queue1, this.queue2 = this.queue2, this.queue1
}
func (this *MyStack) Pop() int {
// 队列1 用来出栈:存储最后进入的元素
v := this.queue1[0]
this.queue1 = this.queue1[1:]
return v
}
func (this *MyStack) Top() int {
return this.queue1[0]
}
func (this *MyStack) Empty() bool {
return len(this.queue1) == 0
}
/**
* Your MyStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(x);
* param_2 := obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.Empty();
*/时间复杂度:O(n),入栈时间复杂度 O(n),其它操作时间复杂度 O(1)
空间复杂度:O(n),使用了2个额外的数组
二)一个队列
思路:
1、queue1 存储栈内的元素
2、入栈操作:记录已有队列元素,将新元素入队列,然后将前n个已有元素入队列,删除前n个元素
3、出栈操作:只要 从 queue1 出栈即可
代码:
type MyStack struct {
queue1 []int
}
func Constructor() MyStack {
return MyStack{}
}
func (this *MyStack) Push(x int) {
n := len(this.queue1)
this.queue1 = append(this.queue1, x)
// 将前n个元素追加到队列尾部
this.queue1 = append(this.queue1, this.queue1[0:n]...)
// 删除前n个元素
this.queue1 = this.queue1[n:]
}
func (this *MyStack) Pop() int {
// 队列1 用来出栈:存储最后进入的元素
v := this.queue1[0]
this.queue1 = this.queue1[1:]
return v
}
func (this *MyStack) Top() int {
return this.queue1[0]
}
func (this *MyStack) Empty() bool {
return len(this.queue1) == 0
}
/**
* Your MyStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(x);
* param_2 := obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.Empty();
*/时间复杂度:O(n),入栈时间复杂度 O(n),其它操作复杂度 O(1)
空间复杂度:O(n),使用了1个额外的数组
今天的分享就到这里了,加下面微信拉你进编程技术交流群

如果对你有帮助,帮我点一下在看或转发,欢迎关注我的公众号
本文介绍了如何使用两个队列实现后入先出(LIFO)栈,支持push、pop、top和empty操作,同时讨论了两种方法的时间和空间复杂度。
92

被折叠的 条评论
为什么被折叠?



