力扣232. 用栈实现队列

134 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

力扣232. 用栈实现队列

一、题目描述:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false 说明:

你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入: ["MyQueue", "push", "push", "peek", "pop", "empty"]

[[], [1], [2], [], [], []]

输出: [null, null, null, 1, 1, false]

解释: MyQueue myQueue = new MyQueue();

myQueue.push(1); // queue is: [1]

myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)

myQueue.peek(); // return 1

myQueue.pop(); // return 1, queue is [2]

myQueue.empty(); // return false

提示:

1 <= x <= 9

最多调用 100 次 push、pop、peek 和 empty

假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/im… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    为了更好的理解栈和队列的数据结构,这里作者使用C语言先编写了一个栈,然后再用栈来实现了队列,对于栈,我们需要一个存储栈的数组,和当前栈内的元素个数以及栈的容量大小。

    stackCreate是将栈初始化。myQueueCreate是利用初始化实现队列的栈...

    基本原理是,两个栈,一个用于入队,一个用于出队,入队的栈,栈顶是队尾,而出队的栈栈顶是队首。如果出队栈空了,就将入队栈pop然后push到出队栈.....

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    是一次通过的。。。。

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    看一看大佬的Go解法~

     type MyQueue struct {
         inStack, outStack []int
     }
     ​
     func Constructor() MyQueue {
         return MyQueue{}
     }
     ​
     func (q *MyQueue) Push(x int) {
         q.inStack = append(q.inStack, x)
     }
     ​
     func (q *MyQueue) in2out() {
         for len(q.inStack) > 0 {
             q.outStack = append(q.outStack, q.inStack[len(q.inStack)-1])
             q.inStack = q.inStack[:len(q.inStack)-1]
         }
     }
     ​
     func (q *MyQueue) Pop() int {
         if len(q.outStack) == 0 {
             q.in2out()
         }
         x := q.outStack[len(q.outStack)-1]
         q.outStack = q.outStack[:len(q.outStack)-1]
         return x
     }
     ​
     func (q *MyQueue) Peek() int {
         if len(q.outStack) == 0 {
             q.in2out()
         }
         return q.outStack[len(q.outStack)-1]
     }
     ​
     func (q *MyQueue) Empty() bool {
         return len(q.inStack) == 0 && len(q.outStack) == 0
     }
     ​
     作者:demigodliu
     链接:https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/tu-jie-guan-fang-tui-jian-ti-jie-yong-zh-4hru/
     来源:力扣(LeetCode)
     著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

三、AC 代码:

 typedef struct{
     int* stack;
     int stackSize;
     int stackCap;
 }Stack;
 ​
 Stack* stackCreate(int capcity){
     Stack* res = malloc(sizeof(Stack));
     res->stack = malloc(sizeof(int) * capcity);
     res->stackSize = 0;
     res->stackCap = capcity;
     return res;
 }
 ​
 void stackPush(Stack* stack,int num){
     stack->stack[stack->stackSize++] = num;
 }
 ​
 int stackPop(Stack* stack) {
     int num = stack->stack[stack->stackSize-1];
     stack->stackSize--;
     return num;
 }
 ​
 int stackTop(Stack* stack){
     return stack->stack[stack->stackSize - 1];
 }
 ​
 bool stackEmpty(Stack* stack){
     if(stack->stackSize == 0) return true;
     else return false;
 }
 ​
 void stackFree(Stack* stack){
     free(stack->stack);
 }
 ​
 typedef struct {
     Stack* Stack_in;
     Stack* Stack_out;
 } MyQueue;
 ​
 ​
 MyQueue* myQueueCreate() {
     MyQueue* res = malloc(sizeof(MyQueue));
     res->Stack_in = stackCreate(100);
     res->Stack_out = stackCreate(100);
     return res;
 }
 ​
 void myQueuePush(MyQueue* obj, int x) {
     stackPush(obj->Stack_in,x);
 }
 ​
 int myQueuePop(MyQueue* obj) {
     if(stackEmpty(obj->Stack_out)){
         while(stackEmpty(obj->Stack_in) == false){
             stackPush(obj->Stack_out,stackPop(obj->Stack_in));
         }
     }
     int x = stackPop(obj->Stack_out);
     return x;
 }   
 ​
 int myQueuePeek(MyQueue* obj) {
     if(stackEmpty(obj->Stack_out)){
         while(stackEmpty(obj->Stack_in) == false){
             stackPush(obj->Stack_out,stackPop(obj->Stack_in));
         }
     }
     return stackTop(obj->Stack_out);
 }
 ​
 bool myQueueEmpty(MyQueue* obj) {
     return stackEmpty(obj->Stack_in) && stackEmpty(obj->Stack_out);
 }
 ​
 void myQueueFree(MyQueue* obj) {
     stackFree(obj->Stack_in);
     stackFree(obj->Stack_out);
 }
 ​
 /**
  * Your MyQueue struct will be instantiated and called as such:
  * MyQueue* obj = myQueueCreate();
  * myQueuePush(obj, x);
  
  * int param_2 = myQueuePop(obj);
  
  * int param_3 = myQueuePeek(obj);
  
  * bool param_4 = myQueueEmpty(obj);
  
  * myQueueFree(obj);
 */

image.png

四、总结:

这个题目是一道经典的数据结构题目,我们使用两个栈来实现队列,同样的我们也可以使用两个队列来实现栈。感兴趣的朋友可以自己实现一下~