大厂面试高频题详解:用栈实现队列

简介: 大厂面试高频题详解:用栈实现队列

正如标题所述,你需要使用两个栈来实现队列的一些操作。
队列应支持push(element),pop() 和 top(),其中pop是弹出队列中的第一个(最前面的)元素。
pop和top方法都应该返回第一个元素的值。

在线评测地址:领扣题库官网

例1:

输入:
    push(1)
    pop()    
    push(2)
    push(3)
    top()    
    pop()     
输出:
    1
    2
    2

例2:

输入:
    push(1)
    push(2)
    push(2)
    push(3)
    push(4)
    push(5)
    push(6)
    push(7)
    push(1)
输出:
[]

解题思路

先考虑只有一个栈的时候,由于栈的先入后出特性FILO,栈中的元素的顺序是反的,我们无法直接访问栈底的元素。但是当把1号栈中所有元素依次弹出并压入到2号栈中,2号栈顶的元素就变成了原来1 号栈的栈底,即正序。所以我们要提取元素时,只需从2号栈提取即可。
但是由于2号栈中栈顶元素是最先加入队列的元素,所以只有当2号栈为空时,才能将1号栈中所有元素加入到2号栈中。
举例说明:
首先我们有一个主要栈stack1:[1,2,3) ,以下所有栈的表示方式中,圆括号 ')' 均为栈顶。 那么stack1的出栈顺序为3-2-1,其中 1 为我们要找到的元素,也就是队首。
我们需要借助一个辅助栈stack2:[),将stack1中的元素依次放到stack2中:stack2 [3,2,1)。这时我们发现stack2的栈顶就是我们要找的元素,弹出即可。
此时我们再向主要栈stack1中压入 4 和 5。两个栈状态:stack1 [4,5) 、stack2 [3,2)。
现在我们需要队首的话,应该先弹出辅助栈stack2的栈顶。
如果此时辅助栈空,我们就要执行之前转移的操作,将stack1的所有元素压入stack2,然后弹出stack2的栈顶即可。
代码思路
定义move(),操作是将元素从1号栈转移到2号栈。当要提取元素,且2号栈为空时,调用move()。

复杂度分析

时间复杂度

  • 每个元素最多会别push,pop,move一次,每个操作的均摊时间复杂度为O(1)。
    空间复杂度
  • 假设一共操作了N次push,空间复杂度为O(N)。
public class MyQueue {
    public MyQueue() {
        // do intialization if necessary
    }
    /*
     * @param element: An integer
     * @return: nothing
     */
    public void push(int element) {
        stack1.push(element);
    }
    /*
     * @return: An integer
     */
    public int pop() {
        if (stack2.isEmpty()) {
            move();
        }
        return stack2.pop();
    }
    /*
     * @return: An integer
     */
    public int top() {
        if (stack2.isEmpty()) {
            move();
        }
        return stack2.peek();
    }
    
    // 将1号栈中的元素移动到2号栈中
    private void move() {
        while (! stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
    }
    
    private Stack<Integer> stack1 = new Stack<>();
    private Stack<Integer> stack2 = new Stack<>();
}

更多题解参考:[九章官网solution
](https://www.jiuzhang.com/solution/implement-queue-by-two-stacks/?utm_source=sc-tianchi-sz-20nov)

相关文章
|
4月前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
331 2
|
7月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
7月前
|
存储 设计模式 Java
Unity精华☀️ 面试“堆、栈”误区!这样做可能反而会降低吸引力
Unity精华☀️ 面试“堆、栈”误区!这样做可能反而会降低吸引力
|
8月前
|
存储 安全 Java
Java面试题:在JVM中,堆和栈有什么区别?请详细解释说明,要深入到底层知识
Java面试题:在JVM中,堆和栈有什么区别?请详细解释说明,要深入到底层知识
120 3
|
8月前
|
存储 缓存 监控
Java面试题:解释堆和栈的OutOfMemoryError通常在什么情况下会发生
Java面试题:解释堆和栈的OutOfMemoryError通常在什么情况下会发生
85 3
|
7月前
|
安全 Java
虚拟机栈的五道面试题
这篇文章提供了关于Java虚拟机栈的五个面试问题,涉及栈溢出的情况、栈大小调整、栈内存的分配、垃圾回收与虚拟机栈的关系以及局部变量的线程安全性。
|
8月前
|
设计模式 安全 Java
Java面试题:请解释Java中的线程池以及为什么要使用线程池?请解释Java中的内存模型以及如何避免内存泄漏?请解释Java中的并发工具包以及如何实现一个简单的线程安全队列?
Java面试题:请解释Java中的线程池以及为什么要使用线程池?请解释Java中的内存模型以及如何避免内存泄漏?请解释Java中的并发工具包以及如何实现一个简单的线程安全队列?
74 1
|
8月前
|
存储 设计模式 监控
Java面试题:简述JVM的内存结构,包括堆、栈、方法区等。栈内存优化的方法有 哪些?
Java面试题:简述JVM的内存结构,包括堆、栈、方法区等。栈内存优化的方法有 哪些?
65 0
|
8月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
101 0
|
8月前
|
Java 开发者
Java面试题:Java内存管理精要与多线程协同策略,Java内存管理:堆内存、栈内存、方法区、垃圾收集机制等,多线程编程的掌握,包括线程创建、同步机制的原理
Java面试题:Java内存管理精要与多线程协同策略,Java内存管理:堆内存、栈内存、方法区、垃圾收集机制等,多线程编程的掌握,包括线程创建、同步机制的原理
68 0

热门文章

最新文章