• LeetCode 图解 | 232.使用栈实现队列


    点击上方蓝字设为星标

    下面开始今天的学习~

    今天分享的题目来源于 LeetCode 第 232 号问题:使用栈实现队列。

    题目描述

    使用栈实现队列的下列操作:

    • 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 topsize和  is empty 操作是合法的。

    • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

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

    题目分析

    这是一道很典型的为初级算法爱好者准备的算法题,首先简单介绍一下 队列 和  这两种数据结构。

    队列

    队列是一种 先进先出(first in - first out, FIFO)的数据结构,队列中的元素都从后端(rear)入队(push),从前端(front)出队(pop)。 

    栈是一种 后进先出(last in - first out, LIFO)的数据结构,栈中元素从栈顶(top)压入(push),也从栈顶弹出(pop)。


    为了满足队列的 FIFO 的特性,我们需要用到两个栈,用它们其中一个来进行入队操作,用另一个来进行出队操作。

    动画演示

    参考代码

    //@author:程序员吴师兄
    class MyQueue {
    
        private Stack<Integer> in = new Stack<>(), out = new Stack<>();
    
        //定义一个辅助函数来处理当 out 为空时,将 in 里面的数据挪到 out 中去
        private void transferIfEmpty() {
             if (out.empty()){
                 while (!in.empty()){
                       out.push(in.pop());
                 }
             }
        }
    
        /** Initialize your data structure here. */
        public MyQueue() {
    
        }
    
        /** Push element x to the back of queue. */
        public void push(int x) {
            in.push(x);
        }
    
        /** Removes the element from in front of queue and returns that element. */
        public int pop() {
          transferIfEmpty();
          return out.pop();
        }
    
        /** Get the front element. */
        public int peek() {
          transferIfEmpty();
          return out.peek();
        }
    
        /** Returns whether the queue is empty. */
        public boolean empty() {
          return in.empty() && out.empty();
        }
    }
    

    复杂度分析

    代码实现中涉及到多个函数,每个函数的复杂度是有所区别的。

    push操作

    • 时间复杂度:O(n) 。通过动画可知,除了新元素之外的其它元素,它们都会被压入两次,弹出两次。新元素只被压入一次,弹出一次。这个过程产生了 4n + 2 次操作,其中 n 是队列的大小。由于 压入 操作和 弹出 操作的时间复杂度为 O(1), 因此时间复杂度为 O(n)。

    • 空间复杂度:O(n)。需要额外的内存来存储队列中的元素,因此空间复杂度为 O(n)。

    pop操作

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

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

    peek操作

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

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

    empty操作

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

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

    知识点

    栈、队列

    END


    ● 深度剖析头条面试真题 | 二叉树那点事儿

    ● 牛逼了,原来大神都是这样学动态规划的...

    ● 不上班的 613 天

    数据结构和算法学习指南

    点“在看”你懂得 

  • 相关阅读:
    Qt助手---摘录
    Qt随记
    前端编码规范之CSS(转)
    给QT新手的练手项目——基于QT的GIF播放器(转)
    Qt收藏
    C++开发者都应该使用的10个C++11特性(转)
    为学Linux,我看了这些书(转)
    Qt去掉view项的焦点虚线框的方法(转)
    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)(转)
    JZOJ 3085. 图的计数
  • 原文地址:https://www.cnblogs.com/csnd/p/16674981.html
Copyright © 2020-2023  润新知