代码随想录第10天 | LeetCode232.用栈实现队列、LeetCode225. 用队列实现栈

day10 | LeetCode232.用栈实现队列、LeetCode225. 用队列实现栈

一、LeetCode232.用栈实现队列:

链接:232. 用栈实现队列 - 力扣(LeetCode)

方法:使用两个栈实现

1. 思路:

使用栈来模拟对了的行为,需要使用两个栈来实现,一个输入栈,一个输出栈。

执行语句:

  1. queue.push(1);
    1. **输入栈:栈底|**1 栈口
    2. 输出栈:栈口 |栈底
  2. queue.push(2);
    1. **输入栈:栈底|**1 ← 2 栈口
    2. 输出栈:栈口 |栈底
  3. queue.pop();
    1. 输入栈:栈口 |栈底
    2. 输出栈:栈口 1 → 2|栈底
    3. pop()输出 1,符合队列的先进先出规则。
  • push():只需要将数据放入输入栈即可。
  • pop():如果输出栈为空,则需要将输入栈的数据全部导入输出栈,再从输出栈弹出数据。如果输出栈不为空,则直接弹出输出栈的数据即可。
  • peek()pop()peek()两个函数功能类似。
  • empty():如果进栈出栈都为空的话,说明模拟的队列为空了。

2. 代码实现:

class MyQueue {

    Stack<Integer> stackIn;
    Stack<Integer> stackOut;
    public MyQueue() {
        // 进栈
        stackIn = new Stack<>();
        // 出栈
        stackOut = new Stack<>();
    }

    // 将元素 x 推到队列的末尾
    public void push(int x) {
        stackIn.push(x);
    }

    // 从队列的开头移除并返回元素
    public int pop() {
        if (stackOut.isEmpty()){
            while (!stackIn.isEmpty()){
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.pop();
    }

    // 返回队列开头的元素
    public int peek() {
        int res = this.pop();
        // 因为 pop 弹出了元素 res , 所有需要添加回去
        stackOut.push(res);
        return stackOut.peek();
    }

    // 如果队列为空, 返回 true ; 否则, 返回 false
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }
}

3.复杂度分析:

入队 push()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

出队 pop()

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

需要将输入栈的所有数据导入到输出栈,所有空间和时间复杂度为O(N)

返回队列开头的元素 peek()

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

是否为空 empty()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

3.思考:

  1. 在工作如果遇到功能相近的函数一定要抽象出来,不要大量的复制粘贴,很容易出问题。

Reference

  1. 代码随想录 (programmercarl.com)
  2. 栈的基本操作! | LeetCode:232.用栈实现队列_哔哩哔哩_bilibili

二、LeetCode225. 用队列实现栈:

链接:225. 用队列实现栈 - 力扣(LeetCode)

方法1:使用两个队列实现

1. 思路:

使用两个队列来实现栈,que2 队列其实就是起到备份的作用。

  • push() :正常加入数据即可。
  • pop():将 que1 队列除最后一个数据全部导入 que2 队列,再把 que1 队列里剩下的数据给弹出,就相当栈的后进先出。再把que2的数据给导回给que1
  • top() :返回队列的尾部数据。
  • empty():判断que1 队列是否为空。

2. 代码实现:

class MyStack {
    // Deque 接口继承了 Queue 接口
    // Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> queue1;
    // 备份
    Deque<Integer> queue2;

    public MyStack() {
        queue1 = new ArrayDeque<>();
        queue2 = new ArrayDeque<>();
    }

    // 将元素 x 压入栈顶
    public void push(int x) {
        queue1.addLast(x);
    }

    // 移除并返回栈顶元素
    public int pop() {
        int size = queue1.size();
        // 将 queue1 数据导入 queue2 ,最后一个数据除外
        size--;
        while (size-- > 0){
            queue2.addLast(queue1.peekFirst());
            queue1.pollFirst();
        }
        Integer res = queue1.pollFirst();
        // 将 que2 对象的引用赋给了 que1
        queue1 = queue2;
        // 为 que2 分配一个新的空间
        queue2 = new ArrayDeque<>();
        return res;
    }

    // 返回栈顶元素
    public int top() {
        return queue1.getLast();
    }

    // 如果栈是空的,返回 true ;否则,返回 false
    public boolean empty() {
        return queue1.isEmpty();
    }
}

3.复杂度分析:

入队 push()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

出队 pop()

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

返回队列开头的元素 peek()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

判断是否为空 empty()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

方法2:使用一个队列实现栈

1. 思路:

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时在去弹出元素就是栈的顺序了。

2. 代码实现:

class MyStack {
    // Deque 接口继承了 Queue 接口
    // Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> queue1;

    public MyStack() {
        queue1 = new ArrayDeque<>();
    }

    // 将元素 x 压入栈顶
    public void push(int x) {
        queue1.addLast(x);
    }

    // 移除并返回栈顶元素
    public int pop() {
        int size = queue1.size();
        // 除了最后一个元素外, 重新添加到队列尾部
        size--;
        while (size-- > 0){
            queue1.addLast(queue1.peekFirst());
            queue1.pollFirst();
        }
        Integer res = queue1.pollFirst();
        return res;
    }

    // 返回栈顶元素
    public int top() {
        return queue1.getLast();
    }

    // 如果栈是空的,返回 true ;否则,返回 false
    public boolean empty() {
        return queue1.isEmpty();
    }
}

3.复杂度分析:

入队 push()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

出队 pop()

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

返回队列开头的元素 peek()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

判断是否为空 empty()

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

Reference

  1. 代码随想录 (programmercarl.com)
  2. 队列的基本操作! | LeetCode:225. 用队列实现栈_哔哩哔哩_bilibili
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值