算法训练营第十天| 232. 用栈实现队列、225. 用队列实现栈

97 阅读3分钟

232. 用栈实现队列

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

实现 MyQueue 类:

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

说明:

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

image.png

思路

题目要求我们使用栈(FILO)来实现先进先出队列。 思路如下:

  • 先准备两个栈,inStackoutStack
  • 每次 入栈操作都推入 inStack
  • 每次出栈先检查outStack是否为空,如果为空,则把inStack中的栈全部推入outStack中,顺便清空inStack中的数据
  • 然后再从outStack中弹出
  • peek() 方法同理
  • empty()方法要同时检查inStackoutStack是否都是空。

下图为pop操作的具体流程图:

image.png

代码实现

class MyQueue {

    LinkedList<Integer> in;
    LinkedList<Integer> out;

    public MyQueue() {
        in = new LinkedList<>();
        out = new LinkedList<>();
    }
    
    public void push(int x) {
        in.push(x);
    }
    
    public int pop() {
        if (out.isEmpty()) {
            in2out();
        }
        return out.pop();
    }
    
    public int peek() {
        if (out.isEmpty()) {
            in2out();
        }
        return out.peek();
    }
    
    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }

    public void in2out() {
        while (!in.isEmpty()) {
            out.push(in.pop());
        }
    }
}
  • 时间复杂度: push()empty()为O(1), pop()peek()为O(n)
  • 空间复杂度: O(n)

225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

 

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

image.png

思路

本题和上题不同,无法用一个进队列和一个出队列解决,具体原因自己模拟以下就能知道。
本题解题的思路在于push()方法,具体操作如下:

  • 准备两个队列:主队列main和备份队列backup
  • 每次push操作发生时,先往备份队列插入,然后将所有主队列的数据转移到备份队列。
  • 交换主队列和备份队列
  • pop()peek()操作都直接从主队列中pop和peek就行。
  • empty()也可以直接调用main.isEmpty()

push()流程如下图

image.png

代码实现

class MyStack {

    LinkedList<Integer> main;
    LinkedList<Integer> backup;

    public MyStack() {
        main = new LinkedList<>();
        backup = new LinkedList<>();
    }
    
    public void push(int x) {
        backup.offer(x);
        while (!main.isEmpty()) {
            backup.offer(main.pop());
        }
        LinkedList<Integer> temp = main;
        main = backup;
        backup = temp;
    }
    
    public int pop() {
        return main.pop();
    }
    
    public int top() {
        return main.peek();
    }
    
    public boolean empty() {
        return main.isEmpty();
    }  
}
  • 时间复杂度: push()为O(n),其他为O(1)
  • 空间复杂度: O(n)