剑指Offer9——使用双栈模拟队列

队列Queue是具有FIFO(First in First out)特性的数据结构,栈Stack是具有LIFO(后进先出)特性的数据结构。下面提供一种思路使用双栈来模拟队列。

1. 思路——为何需要用两个栈?

很显然一个普通的栈是无法替代队列的,这是因为先进栈的元素总是后出栈。

如果输入序列是123(假设push和pop不交替进行),输出序列仅为321,与队列恰好是反过来的。那么,我们产生了一个思路,就像是“负负得正”一样,如果增加一个栈来接收上一个栈所pop出的元素,其输出序列就像一个队列一样。这说明使用两个栈模拟队列在理论上是可行的,但是还有一些细节需要注意。(见实现过程)

2. 实现过程叙述

首先我们设置两个栈:inStack和outStack。

当进行入队操作时,直接将入队元素push进inStack。

当进行出队操作时,这里需要进行一些判断:outStack中的元素是来自于inStack,但是不是说元素进入inStack后直接pop并输出到outStack,因为如果outStack内存在元素,其一定要先于目前在inStack内元素输出,如果现在就直接把inStack内元素pop并输出到outStack中会导致元素顺序混乱(不符合FIFO),因此这里要注意:一定要在outStack为空的前提下再从inStack向其输出元素。也就是说若outStack内有元素就先弹出,若没有则先从inStack内弹出并压入outStack栈,再从outStack栈弹出。这个过程体现在CQueue的deleteHead方法中。

3. 代码示例

class CQueue {
// 推荐使用双端队列模拟栈
private Deque<Integer> inStack;
private Deque<Integer> outStack; public CQueue() {
// 此处使用菱形语法,也可以在菱形内补充Integer
inStack = new ArrayDeque<>();
outStack = new ArrayDeque<>();
} // 直接push进inStack就好
public void appendTail(int value) {
inStack.push(value);
} public int deleteHead() {
/** 此处为代码的关键
** 只有当outStack为空且inStack不为空时操作将inStack元素转移进outStack
** 否则会导致顺序变乱
*/
if(outStack.isEmpty()) {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}
if (!outStack.isEmpty()) return outStack.pop();
// 如果outStack为空,返回-1
return -1;
}
} /**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/

剑指Offer9——使用双栈模拟队列的更多相关文章

  1. 《剑指offer》-双栈实现队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 很基本的STL容器操作了,应该可以1A的,但是忘记返回值的时候,clang的报错感觉并不友好啊.. cl ...

  2. 剑指Offer——Java实现栈和队列的互模拟操作

    剑指Offer--Java实现栈和队列的互模拟操作 栈模拟队列   题目:JAVA实现用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型.   思路:其实就是把队列正常入 ...

  3. 剑指offer-用两个栈实现队列05

    class Solution: def __init__(self): self.stackpush=[] self.stackpop=[] def push(self, node): # write ...

  4. 剑指offer-用两个栈实现队列-栈和队列-python

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型.   # -*- coding:utf-8 -*- class Solution: def __init_ ...

  5. CLRS10.1-6练习 - 用双栈实现队列

    双栈实现队列算法: 分别考虑队列两种操作入队和出队,我们假设使用栈s1 s2, s1用来模拟入队,s2用来模拟出队 入队: 入队操作直接执行s1.push即可 出队: 代码实现 package hel ...

  6. 3-08. 栈模拟队列(25)(ZJU_PAT 模拟)

    主题链接:http://pat.zju.edu.cn/contests/ds/3-08 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q. 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操 ...

  7. 模拟栈&&模拟队列

    模拟栈:class Stack { private List list = new ArrayList( ); public void push( Object obj ) { this.list.a ...

  8. 剑指offer计划25(模拟中等)---java

    1.1.题目1 剑指 Offer 29. 顺时针打印矩阵 1.2.解法 常规开头,先判断特殊情况,然后创建四个变量存放矩阵四边的长度限制. 创建res数组存放结果. 循坏开始,遍历完一行或者一列,就将 ...

  9. 剑指Offer05 用栈模拟队列

    添加了模板类应用 /************************************************************************* > File Name: ...

随机推荐

  1. 【C# GC】C# GC何时被调用

    首先要指导GC的机制,这部分转载自:http://blog.csdn.net/qq_20949153/article/details/52188882CLR:公共运行时环境,管理托管堆.CTR:设置引 ...

  2. 安装grunt-browser-sync时报错:“未能加载Visual C++ 组件 “VCBuild.exe”

    报错环境:windows7 X64 , VS2012 报错内容: MSBUILD : error MSB3428: 未能加载 Visual C++ 组件"VCBuild.exe". ...

  3. shell-if表达式(-f,-d,-s,-r,-w,-x,-eq,-ne,-ge,-gt,-le,-lt )

    文件表达式 if [ -f file ] 如果文件存在if [ -d - ] 如果目录存在if [ -s file ] 如果文件存在且非空if [ -r file ] 如果文件存在且可读if [ -w ...

  4. 获取swiper的索引

    效果: js代码: swiper.on('slideChangeTransitionEnd', function () {         var txt = $('.swptest_bot_righ ...

  5. 安装CentOS时,推荐的分区方案

    最佳分区设置取决于 Linux 系统的用途.

  6. 矩池云上安装yolov4 darknet教程

    这里我是用PyTorch 1.8.1来安装的 拉取仓库 官方仓库 git clone https://github.com/AlexeyAB/darknet 镜像仓库 git clone https: ...

  7. 清华大学ucore操作系统课笔记

    操作系统 清华大学ucore操作系统课笔记 全文思维导图 1. 操作系统概述 1.1 什么是操作系统? 操作系统的定义 没有公认的精确定义 一个控制程序 一个系统软件 控制程序执行过程,防止错误和计算 ...

  8. centos7下rsync+inotify脚本实现文件同步,.NET CORE客户端文件更新后自动重启服务

    源服务器IP:192.168.8.51 目标服务器IP:192.168.8.79 安装前源服务器及目标服务器均需关闭FIREWALLD\SELINUX防火墙 sestatus | grep statu ...

  9. vue3-插槽作用域的使用

    当我们在父组件定义了一个数组, data() { return { name: ["lkx", "msx"] } } 想把它传到子组件处理后 props: { ...

  10. Excel文件导入SQL Server数据库

    Excel表格的使用可谓是非常广泛,博主也简单百度了一下Excel的发展. 发展历程: 1982年 Microsoft推出了它的第一款电子制表软件-Multiplan,并在CP/M系统上大 Excel ...