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

问题描述

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

其中:

  • 1 <= values <= 10000
  • 最多会对 appendTail、deleteHead 进行 10000 次调用
示例 1:

输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]

输出:[null,null,3,-1]


示例 2:

输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]

输出:[null,-1,null,null,5,2]

 

Java 实现

用两个栈实现一个队列的功能,即通过两个先入后出(FILO)实现一个先入先出(FIFO),我们可以用一个栈支持插入操作,另一个栈实现删除操作。

具体的操作为:当我们每一次执行插入元素时,直接往第一个栈 stack1 插入元素,根据栈的结构特性,栈底是第一个插入也是下一个待删除的元素,栈顶是最后插入的元素。当我们想执行删除操作时,需要将 stack1 的元素依次取出,取到最后才能访问到该删除的元素,但同时我们也想保持元素插入的顺序,这时就可以用上第二个栈 stack2。假设第一次执行删除时,stack2位空,则先把 stack1 的元素依次弹出并插入到 stack2 中,直至 stack1完全清空,此时 stack2 的栈顶即为下一个待删除的元素,直至栈底依次为接下来待删除的元素。此后,每次执行删除操作只需从 stack2 弹出元素即可。

当 stack2 栈内存在元素的时候,删除与插入操作分别对 stack2 与 stack1进行操作,且两个栈之间相互独立。即删除操作只在 stack2 进行,插入操作只在 stack1 进行。在 stack2 清空之前,stack1 维持后一批插入的元素及其插入顺序。每次当且仅当 stack2 为空,且需要进行删除操作时,才从 stack1 向 stack2 转移数据。如果转移后 stack2 仍为空,即此时无元素存在,则返回 -1。

class CQueue {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    public CQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    
    public void appendTail(int value) {
        stack1.push(value);
    }
    
    public int deleteHead() {
        if (!stack2.isEmpty()) {
            return stack2.pop();
        } else {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
            if (stack2.isEmpty()) {
                return -1;
            } else {
                return stack2.pop();
            }
        }
    }
}

复杂度分析

  • 空间复杂度:维护两个栈进行存储,因此为 O(n)。
  • 时间复杂度:插入操作,明显为 O(1)。删除操作看似为 O(n),但经过仔细考虑会发现,每次执行删除时只从 stack2 弹出一次,即便 stack2 为空,需要从 stack1 将所有元素都转移一遍,但这个过程同样被均摊到每一个元素的插入和弹出过程中,因此删除操作的时间复杂度为 O(1)。
展开阅读全文

Python数据分析与挖掘

01-08
92讲视频课+16大项目实战+源码+¥800元课程礼包+讲师社群1V1答疑+社群闭门分享会=99元   为什么学习数据分析?       人工智能、大数据时代有什么技能是可以运用在各种行业的?数据分析就是。       从海量数据中获得别人看不见的信息,创业者可以通过数据分析来优化产品,营销人员可以通过数据分析改进营销策略,产品经理可以通过数据分析洞察用户习惯,金融从业者可以通过数据分析规避投资风险,程序员可以通过数据分析进一步挖掘出数据价值,它和编程一样,本质上也是一个工具,通过数据来对现实事物进行分析和识别的能力。不管你从事什么行业,掌握了数据分析能力,往往在其岗位上更有竞争力。    本课程共包含五大模块: 一、先导篇: 通过分析数据分析师的一天,让学员了解全面了解成为一个数据分析师的所有必修功法,对数据分析师不在迷惑。   二、基础篇: 围绕Python基础语法介绍、数据预处理、数据可视化以及数据分析与挖掘......这些核心技能模块展开,帮助你快速而全面的掌握和了解成为一个数据分析师的所有必修功法。   三、数据采集篇: 通过网络爬虫实战解决数据分析的必经之路:数据从何来的问题,讲解常见的爬虫套路并利用三大实战帮助学员扎实数据采集能力,避免没有数据可分析的尴尬。   四、分析工具篇: 讲解数据分析避不开的科学计算库Numpy、数据分析工具Pandas及常见可视化工具Matplotlib。   五、算法篇: 算法是数据分析的精华,课程精选10大算法,包括分类、聚类、预测3大类型,每个算法都从原理和案例两个角度学习,让你不仅能用起来,了解原理,还能知道为什么这么做。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值