剑指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. Linux 中CPU 和 GPU 的行为监控

    由于 Steam(包括 Steam Play,即 Proton)和一些其他的发展,GNU/Linux 正在成为越来越多计算机用户的日常游戏平台的选择.也有相当一部分用户在遇到像视频编辑或图形设计等(K ...

  2. win7下安装Hadoop

    1 下载准备 下载hadoop,官网用一个快一点的镜像,使用迅雷加速下载,二进制格式,解压目录:E:\hadoop\hadoop-2.9.2 下载winutils,这个是别人编译好的hadoop的wi ...

  3. ElasticSearch内部基于_version乐观锁控制机制

    1.悲观锁与乐观锁机制 为控制并发问题,我们通常采用锁机制.分为悲观锁和乐观锁两种机制. 悲观锁:很悲观,所有情况都上锁.此时只有一个线程可以操作数据.具体例子为数据库中的行级锁.表级锁.读锁.写锁等 ...

  4. tp5 Redis缓冲的设置与清除

    控制器代码: //设置缓冲的方法 public function order() { $word = input('word');//接受搜索值 //题意:将订单数据使用redis进行缓存中,第二次读 ...

  5. Android 12(S) 图形显示系统 - BufferQueue/BLASTBufferQueue之初识(六)

    题外话 你有没有听见,心里有一声咆哮,那一声咆哮,它好像在说:我就是要从后面追上去! 写文章真的好痛苦,特别是自己对这方面的知识也一知半解就更加痛苦了.这已经是这个系列的第六篇了,很多次都想放弃了,但 ...

  6. 浏览器中 Http缓存

    分类: web缓存主要有:数据库缓存.服务器缓存(代理服务器缓存.CDN缓存),浏览器缓存. 数据库缓存 当web应用的关系比较复杂,数据库中的表很多的时候,如果频繁进行数据库查询,很容易导致数据库不 ...

  7. 面试官:Redis如何实现持久化的、主从哨兵又是什么?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 作为一名Java程序员,Redi ...

  8. 华为三层交换机5700 DHCP配置

    交换机配置DHCP配置 1,交换机作DHCP Server『配置环境参数』1. PC1.PC2的网卡均采用动态获取IP地址的方式2. PC1连接到交换机的以太网端口0/1,属于VLAN10:PC2连接 ...

  9. 配置DHCP Relay的功能原理是什么?

    DHCP中继代理,就是在DHCP服务器和客户端之间转发DHCP数据包.当DHCP客户端与服务器不在同一个子网上,就必须有DHCP中继代理来转发DHCP请求和应答消息.DHCP中继代理的数据转发,与通常 ...

  10. 网关中间件-Nginx(一)

    一.Nginx介绍 1.nginx是一个高性能HTTP服务器,反向代理服务器,邮件代理服务器,TCP/UDP反向代理服务器. 2.nginx处理请求是异步非阻塞的,在高并发下nginx 能保持低资源低 ...