剑指 Offer 09. 用两个栈实现队列(简单)

Posted 徐同学呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 09. 用两个栈实现队列(简单)相关的知识,希望对你有一定的参考价值。

题干

剑指 Offer 09. 用两个栈实现队列:

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )。

class CQueue 
    public CQueue() 
    
    public void appendTail(int value) 
    
    public int deleteHead() 
    

原题链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5d3i87/

思路解析

队列:先进先出
栈:先进后出

用两个栈实现 队列,假设有两个栈a、b:

  1. 添加元素先入栈a
  2. 删除元素按照队列的特点,是让栈a的最底部的元素出栈
  3. 但是没办法直接删除栈a最底部的元素,所以将栈中的元素顺序出栈到栈b
  4. 这样栈a底部的元素就到了栈B的顶部
  5. 删除栈b顶部元素,就起到了队列先进先出的效果

代码实现

栈 a 用于加入队尾操作,栈 b 用于将元素倒序,从而实现删除队首元素。

加入队尾 appendTail() : 将数字 val 加入栈 a 即可。

删除队首deleteHead() : 有以下三种情况:

  • 当栈 b 不为空: b中仍有已完成倒序的元素,因此直接返回 b 的栈顶元素。
  • 否则,当 a 为空: 即两个栈都为空,无元素,因此返回 -1 。
  • 否则: 将栈 a元素全部转移至栈 b 中,实现元素倒序,并栈 b 的栈顶元素出栈。

用 LinkedList 模拟栈的逻辑,addLast入栈,removeLast出栈。

public class CQueue 
    LinkedList<Integer> a, b;
    public CQueue() 
        a = new LinkedList<Integer>();
        b = new LinkedList<Integer>();
    
    public void appendTail(int value) 
        a.addLast(value);
    
    public int deleteHead() 
        // 判断b中还有元素,出栈,先把b中的元素删完
        if (!b.isEmpty()) 
            return b.removeLast();
        
        // 如果a为空,那就直接返回-1
        if (a.isEmpty()) 
            return -1;
        
        // b为空,且a不为空,
        // 则先将a中的所有元素出栈到b中,让顺序颠倒
        while (!a.isEmpty()) 
            b.addLast(a.removeLast());
        
        // b栈顶元素出栈
        return b.removeLast();
    

    public static void main(String[] args) 
        CQueue queue = new CQueue();
        queue.appendTail(1);
        queue.appendTail(2);
        queue.appendTail(3);
        queue.appendTail(4);

        System.out.println(queue.deleteHead());
        System.out.println(queue.deleteHead());
        System.out.println(queue.deleteHead());
        System.out.println(queue.deleteHead());
    

复杂度分析

时间复杂度:对于插入和删除操作,时间复杂度均为 O(1)。插入不多说,对于删除操作,虽然看起来是 O(n) 的时间复杂度,但是仔细考虑下每个元素只会「至多被插入和弹出 栈2 一次」,因此均摊下来每个元素被删除的时间复杂度仍为 O(1)。

空间复杂度:O(n)。需要使用两个栈存储已有的元素。

特别鸣谢:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/px2ds5/ 带我走上刷题之路!

以上是关于剑指 Offer 09. 用两个栈实现队列(简单)的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 09. 用两个栈实现队列(简单)

双栈实现队列剑指 Offer 09. 用两个栈实现队列

剑指Offer09用两个栈实现队列

剑指Offer09用两个栈实现队列

leetcode剑指 Offer 09. 用两个栈实现队列

剑指 Offer 09. 用两个栈实现队列