【算法挑战】用栈实现队列(含解析、源码)

编程入门 行业动态 更新时间:2024-10-25 07:18:47

【算法挑战】用栈实现<a href=https://www.elefans.com/category/jswz/34/1771257.html style=队列(含解析、源码)"/>

【算法挑战】用栈实现队列(含解析、源码)

232.用栈实现队列

/

  • 232.用栈实现队列
    • 题目描述
    • 方法 1
      • 思路
      • 复杂度
      • 代码
    • 方法 2
      • 思路
      • 复杂度
      • 代码(JavaScript/C++)

题目描述

使用栈实现队列的下列操作:push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
示例:MyQueue queue = new MyQueue();queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false
说明:你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。来源:力扣(LeetCode)
链接:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法 1

思路

由于队列是 FIFI (先进先出),而栈是 FILO (先进后出)。如果要用栈来模拟队列,则每次往模拟队列增加元素的时候,这个元素需要放在栈底,因为它是最后才会出列。

方法之一是,每次需要往模拟队列尾端 push 一个新元素时:

  • 先把栈中的全部元素暂时取出
  • 将新元素入栈到栈底
  • 再将刚刚取出来元素重新入栈

因此我们还需要一个辅助栈来存暂时取出来的元素。

复杂度

  • 时间复杂度:入列操作是 O ( n ) O(n) O(n),每次入列时,除新增元素外,每个元素都需要分别出栈入栈 2 次 (从模拟队列的栈中弹出,压入辅助栈,再从辅助栈弹出,压入队列模拟栈)。压入、弹出操作的时间复杂度都是 O ( 1 ) O(1) O(1),所以总的时间复杂度差不多是 O ( 4 n ) O(4n) O(4n),忽略掉常数,最后得到 O ( n ) O(n) O(n)。出列操作是 O ( 1 ) O(1) O(1)。
  • 空间复杂度: O ( n ) O(n) O(n),n 是队列的大小,需要一个大小为 n 的栈来模拟队列,还需要一个大小为 n 的辅助空间,但总的空间复杂度还是 O ( n ) O(n) O(n)。

代码

JavaScript Code

class MyQueue {constructor() {this.stack = [];}push(x) {const helper = [];while (!this.empty()) {helper.push(this.stack.pop());}this.stack.push(x);while (helper.length) {this.stack.push(helper.pop());}}peek() {return this.stack[this.stack.length - 1];}pop() {return this.stack.pop();}empty() {return this.stack.length === 0;}
}

方法 2

思路

方法 1 是在元素入列的时候,就考虑好了它出列的顺序,但我们还可以转换一下思路,在元素需要出列的时候再来考虑这个问题,这样的话:

  1. 入列时,直接 push 到栈中;
  2. 出列时,由于先入列的元素在栈底,需要先把其他元素弹出,依次压入辅助栈;
  3. 栈底元素弹出,出列;
  4. 刚才出栈的其他元素依次从辅助栈弹出,重新压入模拟栈。

再仔细想想的话:

  • 第 2 步中,辅助栈中的元素出栈顺序刚好就是队列的出列顺序;
  • 所以到第 4 步的时候,我们根本没必要把元素再从辅助栈转移到模拟栈;
  • 下一次 pop 操作时,直接从辅助栈弹出元素就可以了;
  • 如果辅助栈中没有元素了,我们再重复第 2 步。

这样的话,我们的队列元素其实是用了两个栈来储存,所以在判断队列是否为空的时候,两个栈都要考虑进去。

复杂度

  • 时间复杂度:入列是 O ( 1 ) O(1) O(1),出列最差的情况就是每个元素都要从模拟栈中弹出,压入辅助栈,再从辅助栈中弹出,所以是 O ( n ) O(n) O(n)。
  • 空间复杂度: O ( n ) O(n) O(n),n 为队列大小。

代码(JavaScript/C++)

JavaScript Code

class MyQueue {constructor() {this.stack = new MyStack();this.helper = new MyStack();}push(x) {this.stack.push(x);}peek() {if (this.helper.empty()) {while (!this.stack.empty()) {this.helper.push(this.stack.pop());}}return this.helper.peek();}pop() {if (this.helper.empty()) {while (!this.stack.empty()) {this.helper.push(this.stack.pop());}}return this.helper.pop();}empty() {return this.stack.empty() && this.helper.empty();}
}class MyStack {constructor() {this.stack = [];}push(x) {this.stack.push(x);}pop() {return this.stack.pop();}peek() {return this.stack[this.stack.length - 1];}empty() {return this.stack.length === 0;}
}

C++ Code

#include <stack>
using namespace std;class MyQueue {
private:stack<int> stack_in_;stack<int> stack_out_;void pour_to_stack_out_() {while (!stack_in_.empty()) {int top = stack_in_.top();stack_in_.pop();stack_out_.push(top);}};
public:/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {stack_in_.push(x);}/** Removes the element from in front of queue and returns that element. */int pop() {if (stack_out_.empty()) { pour_to_stack_out_();}int top = stack_out_.top();stack_out_.pop();return top;}/** Get the front element. */int peek() {if (stack_out_.empty()) { pour_to_stack_out_();}return stack_out_.top();}/** Returns whether the queue is empty. */bool empty() {return stack_in_.empty() && stack_out_.empty();}
};/*** Your MyQueue object will be instantiated and called as such:* MyQueue* obj = new MyQueue();* obj->push(x);* int param_2 = obj->pop();* int param_3 = obj->peek();* bool param_4 = obj->empty();*/

更多题解可以访问:

总结

以上就是本文所有内容了,希望能对你有所帮助,能够解决用栈实现队列问题。

如果你喜欢本文,也请务必点赞、收藏、评论、转发,这会对我有非常大的帮助。请我喝杯冰可乐也是极好的!

已完结,欢迎持续关注。下次见~

更多推荐

【算法挑战】用栈实现队列(含解析、源码)

本文发布于:2023-12-02 00:10:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1651766.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:队列   算法   源码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!