9. 用兩個棧實現隊列(劍指 Offer 題解Java版)

2020-12-23 酷扯兒

本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫

文章目錄

9. 用兩個棧實現隊列題目連結題目描述解題思路分析Java實現棧Java實現隊列用兩個棧實現隊列

9. 用兩個棧實現隊列

題目連結

牛客網

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github

題目描述

用兩個棧來實現一個隊列,完成隊列的 Push 和 Pop 操作。

解題思路

in棧用來處理入棧(push)操作,out棧用來處理出棧(pop)操作。一個元素進入in棧之後,出棧的順序被反轉。當元素要出棧時,需要先進入out棧,此時元素出棧順序再一次被反轉,因此出棧順序就和最開始入棧順序是相同的,先進入的元素先退出,這就是隊列的順序。

分析

棧的特點是先進後出,而隊列的特點是先進先出,主要就是在兩個棧中來回倒騰從而實現隊列的功能,就好像一個黑盒子,裡邊是兩個棧的操作,但其他人在用這個黑盒子的時候,感覺就像在用隊列一樣。隊列和棧只是邏輯性的數據結構,實現隊列和棧可以用數組實現,也可以用鍊表實現,只要滿足隊列先進先出,棧先進後出的特性就可以。

用兩個棧實現隊列,比如一開始在stack1中把a,b,c入棧,想刪除虛擬隊列的隊首元素時,即刪除a,但是a在棧底,無法直接刪除,所以這個時候就要利用stack2了,在進行刪除操作時,可以把stack1中的c,b,a依次彈出併入棧到stack2中,此時a就在stack2的棧頂了,可以直接pop掉。現在b變成stack2的棧頂元素了,繼續刪除b,直接就可以pop,這就完成了隊列的pop操作。那麼怎麼插入一個新元素呢,比如插入d,那麼可以讓d直接入棧到stack1。繼續刪除隊列隊首元素,從stack2中刪除c,然後把d彈出stack1併入棧stack2,然後從stack2中直接pop。通過觀察我們發現,如果進行虛擬隊列的push操作,可以把元素直接入棧到stack1;如果進行虛擬隊列的pop操作,如果stack2為空,那麼把stack1中所有的元素彈出併入棧到stack2,然後對stack2進行pop操作;如果stack2不為空,那麼直接對stack2進行pop操作,到這裡你是不是已經思路變得清晰了。

我們先來用Java的LinkedList鍊表數據結構來實現鏈式棧和鏈式隊列,為後面的用兩個棧實現隊列和用兩個隊列實現棧來服務。

Java實現棧

package 用兩個棧實現隊列;/*

作者 :XiangLin

文件 :stackDemo.java

IDE :IntelliJ IDEA

*/

import java.util.Iterator;

import java.util.LinkedList;

/**

* 棧

*/

public class stackDemo {

private LinkedList<String> stackList = new LinkedList<>();

/**

* 入棧

*/

public void push(String str){

stackList.addFirst(str);

}

/**

*

*/

public String pop(){

return stackList.removeFirst();

}

/**

* 判斷是否為空

*/

public boolean empty(){

return stackList.isEmpty();

}

/**

* 列印棧內所有元素

*/

public void printStack(){

Iterator iterator = stackList.iterator();

while (iterator.hasNext()){

System.out.println(iterator.next() + " ");

}

System.out.println();

}

public static void main(String[] args) {

stackDemo stack = new stackDemo();

System.out.println(stack.empty());

stack.printStack();

stack.push("a");

stack.push("b");

stack.push("c");

System.out.println(stack.empty());

stack.printStack();

}

}

輸出:

true

false

c

b

a

Java實現隊列

package 用兩個棧實現隊列;/*

作者 :XiangLin

文件 :QueueDemo.java

IDE :IntelliJ IDEA

*/

import java.util.Iterator;

import java.util.LinkedList;

/**

* 隊列

*/

public class QueueDemo {

private LinkedList<String> queueList = new LinkedList<String>();

/**

* 入隊列

*/

public void push(String str){

queueList.add(str);

}

/**

* 出隊列

*/

public String pop(){

return queueList.removeFirst();

}

/**

* 獲得隊列元素個數

*/

public int getQueueSize(){

return queueList.size();

}

/**

* 判斷隊列是否為空

*/

public boolean empty(){

return queueList.isEmpty();

}

/**

* 列印隊列內所有元素

*/

public void printQueue(){

Iterator iterator = queueList.iterator();

while(iterator.hasNext()) {

System.out.println(iterator.next()+" ");

}

System.out.println();

}

public static void main(String[] args) {

QueueDemo queueDemo = new QueueDemo();

queueDemo.push("a");

queueDemo.push("b");

queueDemo.push("c");

System.out.println(queueDemo.queueList.size());

queueDemo.pop();

queueDemo.printQueue();

System.out.println(queueDemo.queueList.size());

}

}

輸出:

3

b

c

2

用兩個棧實現隊列

package 用兩個棧實現隊列;/*

作者 :XiangLin

文件 :TwoStackToQueue.java

IDE :IntelliJ IDEA

*/

/**

* 用兩個棧實現隊列

*/

public class TwoStackToQueue {

stackDemo stack1 = new stackDemo();

stackDemo stack2 = new stackDemo();

/**

* 入隊列

*/

public void push(String str){

stack1.push(str);

}

/**

* 出隊列

*/

public String pop(){

if (stack2.empty()){

// 如果棧2為空,就要把棧1所有元素反彈到棧2中

while (!stack1.empty()){

stack2.push(stack1.pop());

}

}

return stack2.pop();

}

/**

* 判斷新隊列是否為空

*/

public boolean empty(){

if(stack1.empty() && stack2.empty()){

return true;

}else {

return false;

}

}

/**

* 列印隊列中所有元素

*/

public void printQueue(){

System.out.println("棧1中:");

stack1.printStack();

System.out.println("棧2中:");

stack2.printStack();

}

public static void main(String[] args) {

TwoStackToQueue queue = new TwoStackToQueue();

queue.push("a");

queue.push("b");

queue.push("c");

queue.printQueue();

queue.pop();

queue.printQueue();

}

}

輸出:

棧1中:

c

b

a

棧2中:

棧1中:

棧2中:

b

c

相關焦點

  • 18.1在 O(1) 時間內刪除鍊表節點(劍指 Offer 題解Java版)
    測試用例功能測試(多個結點鍊表,刪除頭結點、中間結點和尾結點;單個結點鍊表)特殊測試(頭結點或刪除結點為null)package 劍指offer.在O時間內刪除鍊表節點;/*作者 :XiangLin
  • 剪繩子(劍指 Offer 題解Java版)
    證明:當 n >= 5 時,3(n - 3) - n = 2n - 9 > 0,且 2(n - 2) - n = n - 4 > 0。因此在 n >= 5 的情況下,將繩子剪成一段為 2 或者 3,得到的乘積會更大。
  • 數值的整數次方(劍指 Offer 題解Java版)
    數值的整數次方題目連結題目描述解題思路實現代碼16實現代碼package 數值的整數次方;/*作者 :XiangLin文件 :Solution.javaIDE :IntelliJ IDEA
  • 二進位中 1 的個數(劍指 Offer 題解Java版)
    NowCoder題目描述任意給定一個32位無符號整數n,求n的二進位表示中1的個數,比如n = 5(0101)時,返回2,n = 15(1111)時,返回4這也是一道比較經典的題目了,相信不少人面試的時候可能遇到過這道題吧,下面介紹了幾種方法來實現這道題
  • 二叉樹的下一個結點(劍指 Offer 題解Java版)
    二叉樹的下一個結點題目連結題目描述解題思路代碼實現8. 二叉樹的下一個結點題目連結牛客網https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?
  • 重建二叉樹(劍指 Offer 題解Java版)
    重建二叉樹題目連結牛客網https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?解題思路前序遍歷序列的第一個元素 3 就是二叉樹的根節點,中序遍歷序列的根節點 3 把這個序列分成兩半部分,分別是[9]和[20,15,7],左半分部是根節點的左子樹,右半分布是根節點的右,樹。,基於這個特點,我們可以採用遞歸的方法來做,其大致邏輯如下。
  • 二維數組中的查找(劍指 Offer 題解Java版)
    Consider the following matrix:[[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9, 16, 22],>FindTarget find = new FindTarget();int[][] martix = {{1, 4, 7, 11, 15},{2, 5, 8, 12, 19},{3, 6, 9,
  • 解讀 java 並發隊列 BlockingQueue
    是因為 BlockingQueue 支持當獲取隊列元素但是隊列為空時,會阻塞等待隊列中有元素再返回;也支持添加元素時,如果隊列已滿,那麼等到隊列可以放入新元素時再放入。BlockingQueue 是一個接口,繼承自 Queue,所以其實現類也可以作為 Queue 的實現來使用,而 Queue 又繼承自 Collection 接口。
  • 20.表示數值的字符串(劍指 Offer 題解,面試遇到好多次)
    題目描述思路思路一:思路二:題目描述請實現一個函數用來判斷字符串是否表示數值>「1a3.14」「1.2.3」「±5」「12e+4.3」思路思路一:利用正則表達式,對字符串中的每個字符進行判斷分析package 劍指
  • 《三國志14》龜甲隊列使用心得分享 龜甲隊列強度評測
    導 讀 三國志14威力加強版龜甲隊列使用心得 龜甲隊列強度分析 三國志14目前已經推出威力加強版DLC,
  • 高性能內存隊列Disruptor原理分析
    其實JDK已經為我們提供了很多開箱即用的線程間通信的消息隊列,如:ArrayBlockingQueue、LinkedBlockingQueue、ConcurrentLinkedQueue等,這些都是基於無鎖的CAS設計。那麼Disruptor為什麼還有存在的意義呢?
  • 輕量級消息隊列RedisQueue
    消息隊列(Message Queue)是分布式系統必不可少的中間件,大部分消息隊列產品(如RocketMQ/RabbitMQ/Kafka等)要求團隊有比較強的技術實力,不適用於中小團隊,並且對.NET技術的支持力度不夠。而Redis實現的輕量級消息隊列很簡單,僅有Redis常規操作,幾乎不需要開發團隊掌握額外的知識!
  • offer2是哪個律所 offer2四位帶教律師是誰
    《令人心動的offer第二季》是由騰訊視頻推出的一檔職場觀察類真人秀,由何炅、撒貝寧、範丞丞、周深、楊天真和徐靈菱擔任加油團固定成員。那麼,offer2是哪個律所?offer2四位帶教律師是誰?一起來了解一下吧! offer2是哪個律所?
  • 計算機學院優秀碩士offer獲得者經驗問答
    張靜宜:一定要早做準備,在寒假期間就可以看看劍指offer等專業性書籍,同時要在LeetCode上多做題,鍛鍊自己的算法編程能力。    溫超:職業生涯的第一份工作非常重要。首先,應根據自己的實際情況做好自己的職業規劃,可以依據本人情況按照地域、行業、崗位、薪資和工作強度等方面的偏好進行選擇。其次,在確定了自己的擇業方向之後就要早做準備,凡事預則立不預則廢。
  • 案例︱令人痛心的offer,小李用青春換的
    案例︱令人痛心的offer,小李用青春換的 2020-12-15 09:02 來源:澎湃新聞·澎湃號·政務
  • 國產版職場觀察綜藝《令人心動的offer》,照搬韓版,沒有中國味
    結果這次國內翻拍的節奏變得更快了,《新職員誕生記:好人》是2019年4月份出的,這才10月份,國內翻拍版就出來了,叫作《令人心動的offer》。原版「心動」系列的厲害之處,就是它既普世,又創新;既有人氣,又有口碑,已經成為了韓國最厲害的素人綜藝系列之一。比如《心臟信號》,就以一己之力革新了韓綜戀愛綜藝的舊模式。
  • 「分布式架構」最終一致性:暗示的切換隊列
    為了理解最終的一致性,我們需要知道兩個概念:暗示切換隊列和反熵,這兩個概念都需要特別注意。 第一部分 什麼是暗示的切換隊列? 儘管有一個很酷的名字,暗示切換(HH)隊列並沒有得到很多關注。HH隊列有一項非常重要的工作,但是除非您是系統管理員,否則很少直接與它交互。
  • Creator 迷宮生成:DFS與BFS 算法實現
    前言: 我的迷宮代碼的實現受到 [liuyubobobo] 的影響。 liuyubobobo 迷宮的實現: GUI 部分使用 java Swing,程式語言是 Java。
  • 軍營版「貪吃蛇」上線!不一樣的視角解讀班隊列動作
    大家一定看過立正、齊步行進、正步行進等隊列動作,也有很多朋友上學時經歷過軍訓的美好時光。但是,有幾個班的隊列動大家一定很少見,軍訓時教官一定也沒有組織訓練過。
  • RabbitMQ 消費端限流、TTL、死信隊列
    如需轉載與原文作者聯繫作者:向海www.cnblogs.com/haixiang/p/10905189.html前幾天,師長已經帶大家了解了:RabbitMQ 簡介以及使用場景,以及帶大家進行了:手把手帶你Springboot整合RabbitMq ,一篇講完,然後還帶大家用