數據結構(Java):隊列Queue集合力扣面試OJ題

1、隊列

1.1 隊列的概念

隊列是一個特殊的線性表,只允許在一端(隊尾)進行插入數據操作,在另一端(對頭)進行刪除數據。隊列具有先進先出FIFO(First In First Out)的特性。

入隊:數據只能從隊尾進隊列? ? ? ?出隊:數據只能從對頭出隊列

即:隊尾進隊頭出

我們可以把隊列想象為一個排隊的隊伍,從隊尾開始排隊,排到了再從隊頭出隊:

1.2 隊列的設計

實現隊列,我們可以使用單鏈表、雙向鏈表、數組來實現。

  1. 單鏈表:我們可以使用last來作為標記尾結點的引用,入隊時采用尾插法,出隊時采用頭刪法,這樣出隊和入隊時的時間復雜度都可以達到O(1)。注意:入隊不可以采用頭插法,因為出隊時還需要找尾結點的前一個節點,時間復雜度必為O(n)。
  2. 雙向鏈表:因為具有next和prev域,頭插、尾插入隊都是可以的,都為O(1)。
  3. 數組:普通的數組實現隊列會產生很多空間的浪費,每當數據出隊時,front前面的空間就會被浪費掉。我們可以設計循環隊列來減少空間浪費。

接下來我們來聊一聊如何設計循環隊列。

?1.2.1 循環隊列

循環隊列又叫做環形隊列,通常是由數組實現的。

我們定義front和rear分別指向隊頭和隊尾,rear的位置就是入隊元素要插入的位置,起始時front和rear都在0下標處。

循環隊列就是將數組的兩端相連接,這樣即使有元素出隊,出隊元素的位置,rear指針也可以達到,能夠讓新元素入隊,減少空間的浪費。

當在rear為7下標時,進行入隊操作后(假設隊列不為滿),rear要來到0下標的位置,那么要進行的操作是:rear == (rear+1)% len

于是更新rear的操作為:rear == (rear+1)% len

如果基于以上的設計,那么循環隊列為空和隊列為滿時的條件均為:rear == front

那么對于循環隊列,該如何進行判空和判滿呢?我們給出改善設計:

判空:rear == front

判滿(三種方法):

  1. 通過添加 size 屬性記錄(記錄元素個數,size == 數組長度時為滿)
  2. ?浪費一個位置,判斷rear的下一個是不是front。(front == (rear+1)% len時,說明隊列滿)
  3. ?使用標記(在有元素的地方定義boolean類型為true,沒有元素的地方定義為false,當front和rear相遇且boolean類型為true時,說明隊列滿)

1.2.2 實現循環隊列

我們通過一道OJ題來設計循環隊列。(使用浪費一個空間的方法來判滿)

. - 力扣(LeetCode)

?代碼:

class MyCircularQueue {public int front;public int rear;public int[] elem;public MyCircularQueue(int k) {//題目要求我們k個位置均能存儲數據//因為我們使用浪費一個空間的方法來判滿,所以我們這里要開辟k+1個空間elem = new int[k + 1];}public boolean enQueue(int value) {if(isFull()) {//不滿時才能入隊return false;}//在rear位置插入數據,并更新rearelem[rear] = value;rear = (rear+1) % elem.length;return true;}public boolean deQueue() {if(isEmpty()) {//不空時才能出隊return false;}//直接更新front即可,新數據入隊會覆蓋front = (front+1) % elem.length;return true;}public int Front() {if(isEmpty()) {return -1;} //front指向的位置就是隊頭元素return elem[front];}public int Rear() {if(isEmpty()) {return -1;}//當rear == 0時,需要做特殊處理//其余rear-1下標就是隊尾元素的位置int index = rear == 0 ? elem.length - 1 : rear - 1;return elem[index];}public boolean isEmpty() {return rear == front;}public boolean isFull() {return (rear+1) % elem.length == front;}
}

2、隊列Queue

在Java中,Queue是一個接口,底層是用鏈表來實現的:

注意:Queue是一個接口,在實例化時必須實例化實現Queue接口的類的對象。

2.1?Queue的方法

2.2、雙端隊列(Deque)

雙端隊列,元素可以在隊頭和隊尾任意插入和刪除元素,也就是說,元素可以從隊頭出隊和入隊,也可以從隊尾出隊和入隊。

Java給出的雙端隊列Deque也是一個接口(Queue的擴展接口)在實例化時必須實例化實現Deque接口的類的對象。

2.3 使用Queue和Deque

在Java中,有多個類實現了Queue和Deque,這里我們只談LinkedList和ArrayDeque。

我們可以使用LinkedList來實現隊列和雙端隊列,為鏈式實現,底層為鏈表。

也可以使用ArrayDeque來實現隊列和雙端隊列,為順序實現,底層為數組。

同時,LinkedList和ArrayDeque中也實現了集合類Stack中的方法(Deque接口中包含了Stack的方法,而LinkedList和ArrayDeque實現了Deque接口),所以我們也可以使用LinkedList和ArrayDeque來實現棧。

注意:只有Deque接口中包含了Stack的方法,Queue接口沒有包含。

也就是說,我們以后如果要構建棧、隊列、雙端隊列...都可以通過LinkedList和ArrayDeque來實現,其方法更加豐富。


3、面試OJ題

3.1 用隊列實現棧

. - 力扣(LeetCode)

3.1.1 思路分析

我們需要兩個隊列來模擬實現棧。

入棧:把數據放到不為空的隊列當中,如果兩個隊列都為空,則隨機放入即可。

出棧:兩個隊列必有一個為空,將不為空的隊列中的size-1個元素移到空隊列中,剩下的1個元素就是要模擬“出棧”的元素。

取棧頂元素:兩個隊列必有一個為空,將不為空的隊列中的全部元素移到空隊列中,并使用變量記錄每次進新隊列元素的數值,最后一次進隊的元素就是“棧頂”元素。

?3.1.2 代碼

class MyStack {Queue<Integer> qu1;Queue<Integer> qu2;public MyStack() {qu1 = new LinkedList<>();qu2 = new LinkedList<>();}//模擬入棧:把元素放到不為空的隊列中public void push(int x) {if (empty()) {//兩個隊列都為空時 默認放到qu1中qu1.offer(x);} else if (qu1.isEmpty()) {qu2.offer(x);}else {qu1.offer(x);}}//將有元素的隊列中的size-1個元素導入進空隊列中//剩下的1個元素,就是要出棧的元素public int pop() {if (qu1.isEmpty()) {while (qu2.size() != 1) {int x = qu2.poll();qu1.offer(x);}return qu2.poll();}else {while (qu1.size() != 1) {int x = qu1.poll();qu2.offer(x);}return qu1.poll();}}//將有元素的隊列中的全部元素導入進空隊列中//并用變量記錄每一次導進的元素,最后一次導入的元素就是棧頂元素public int top() {int x = 0;if (qu1.isEmpty()) {while (!qu2.isEmpty()) {x = qu2.poll();qu1.offer(x);}return x;}else {while (!qu1.isEmpty()) {x = qu1.poll();qu2.offer(x);}return x;}}//當兩個隊列都為空時,說明棧為空public boolean empty() {return qu1.isEmpty() && qu2.isEmpty();}
}

3.2 用棧實現隊列

. - 力扣(LeetCode)

3.2.1 思路分析

模擬入隊操作:“入隊”的元素全部放入第一個棧中
模擬出隊操作:
需要先判斷第2個棧為不為空,
1.如果未空,需要把第一個棧當中的所有元素都放到第二個棧中,彈出第二個棧當中的棧頂元素
2.如果不為空,直接彈出第二個棧當中的棧頂元素

也就是說第二個棧的棧頂元素,其實就是我們所模擬隊列的隊頭元素。

?3.2.2 代碼

class MyQueue {ArrayDeque<Integer> stack1;//"入隊"的元素統一放到stack1中ArrayDeque<Integer> stack2;//統一在stack2中出隊public MyQueue() {stack1 = new ArrayDeque<>();stack2 = new ArrayDeque<>();}public void push(int x) {stack1.push(x);//"入隊"的元素統一放到stack1中}public int pop() {if (stack2.isEmpty()) {//若stack2為空,則將stack1中的元素導入stack2中,// stack2的棧頂元素即為模擬出隊的“隊頭”元素while (!stack1.isEmpty()) {int x = stack1.pop();stack2.push(x);}return stack2.pop();}else {//若stack2不為空,其棧頂元素即為模擬出隊的“隊頭”元素return stack2.pop();}}public int peek() {if (stack2.isEmpty()) {while (!stack1.isEmpty()) {int x = stack1.pop();stack2.push(x);}return stack2.peek();}else {return stack2.peek();}}public boolean empty() {//當stack1和stack2均為空時,說明模擬的隊列為空return stack1.isEmpty() && stack2.isEmpty();}
}

OK~本次博客到這里就結束了,

感謝大家的閱讀~歡迎大家在評論區交流問題~

如果博客出現錯誤可以提在評論區~

創作不易,請大家多多支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/44539.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44539.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44539.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

有獎競猜!斗牛士軍團與法蘭西騎士的終極之戰,誰將笑傲歐洲之巔?

痛快看球&#xff0c;暢玩游戲&#xff0c;AGON愛攻帶你進入酣暢淋漓的足球世界&#xff01; 7月15日&#xff0c;綠茵賽場硝煙再起&#xff0c;兩支身披榮光的王者之師&#xff0c;一路過關斬將&#xff0c;最終會師決賽。一場萬眾矚目的巔峰對決即將拉開帷幕&#xff0c;究竟…

linux UDP通訊:接口函數示例

一、主要用的接口&#xff1a; //服務器端 1. socket() 創建套接字 2. bind() 綁定套接字 與TCP區別開來&#xff0c;沒有listen()、accept()建立連接的過程 3. 通信 recvfrom() sendto() 4. close //客戶端 1. socket() 創建套接字 與TCP區別開來&#xff0c;沒有connect()建立…

數據結構——排序算法(冒泡、快速、選擇、插入)

文章目錄 1. 概念 2. 十大排序算法 3. 冒泡排序 4. 冒泡代碼實現 5. 快速排序 6. 快速代碼實現 7. 選擇排序 8. 選擇代碼實現 9. 插入排序 10. 插入代碼實現 1. 概念 排序&#xff08;Sort&#xff09;是將無序的記錄序列&#xff08;或稱文件&#xff09;調整成有序…

LabVIEW前面板占滿整個屏幕(轉)

希望在運行一個LabVIEW程序時&#xff0c;它的前面板能夠占據整個屏幕&#xff0c;且不顯示Windows的任務欄或其他任何的LabVIEW菜單選項。怎樣才能實現這一功能&#xff1f; 您可以通過手動配置或編程的方式實現該功能。 手動配置VI屬性 您可以通過以下操作&#xff0c;將…

導入項目,JAVA文件是咖啡杯圖標

問題 從圖中可以看到&#xff0c;JAVA文件是咖啡杯圖標 原因 項目沒有識別為MAVEN項目 解決辦法 進入pom.xml文件&#xff0c;右鍵點擊Add as Maven Project即可

在Ubuntu 16.04上安裝和保護MongoDB的方法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 簡介 MongoDB 是一個免費且開源的面向文檔的數據庫。它被歸類為 NoSQL 數據庫&#xff0c;因為它不依賴于傳統的基于表的關系型數據庫結…

Spring MVC入門3

看完這篇博客你能學到什么 理解JSON的使用理解注解PathVariable理解解注解RequestPart理解cookie和Session的基本概念理解cookie和Session的區別 如果想真正掌握&#xff0c;還需要自己勤加練習。 正文 JSON JSON概念 JSON&#xff1a;JavaScript Object Notation 【JavaS…

【YOLOv8】 用YOLOv8實現數字式工業儀表智能讀數(一)

上一篇圓形表盤指針式儀表的項目受到很多人的關注&#xff0c;咱們一鼓作氣&#xff0c;把數字式工業儀表的智能讀數也研究一下。本篇主要講如何用YOLOV8實現數字式工業儀表的自動讀數&#xff0c;并將讀數結果進行輸出&#xff0c;若需要完整數據集和源代碼可以私信。 目錄 &…

gin源碼分析

一、高性能 使用sync.pool解決頻繁創建的context對象&#xff0c;在百萬并發的場景下能大大提供訪問性能和減少GC // ServeHTTP conforms to the http.Handler interface. // 每次的http請求都會從sync.pool中獲取context&#xff0c;用完之后歸還到pool中 func (engine *Engin…

在C++中怎樣使用C庫

在C中使用C庫是一個相對直接的過程&#xff0c;因為C是從C發展而來的&#xff0c;并且與C高度兼容。這意味著你可以直接在C代碼中使用C庫函數、頭文件和變量&#xff0c;而無需進行特殊轉換。以下是一些基本的步驟和注意事項&#xff0c;用于在C中使用C庫&#xff1a; 1. 包含…

c語言位操作符相關題目之交換兩個數的值

文章目錄 一、題目二、方法11&#xff0c;思路2&#xff0c;代碼實現 三、方法21&#xff0c;思路2&#xff0c;代碼實現 四、方法31&#xff0c;思路2&#xff0c;代碼實現 總結 提示&#xff1a;以下是本篇文章正文內容&#xff0c;下面案例可供參考 一、題目 實現兩個變量的…

淺談PostCSS

1. 背景 css的預處理器語言&#xff08;比如 sass&#xff0c; less&#xff0c; stylus&#xff09;的擴展性不好&#xff0c;你可以使用它們已有的功能&#xff0c;但如果想做擴展就沒那么容易。 sass是很常用的css預處理器語言&#xff0c;在webpack中要使用它&#xff0c;…

設計模式使用場景實現示例及優缺點(結構型模式——組合模式)

結構型模式 組合模式&#xff08;Composite Pattern&#xff09; 組合模式使得用戶對單個對象和組合對象的使用具有一致性。 有時候又叫做部分-整體模式&#xff0c;它使我們樹型結構的問題中&#xff0c;模糊了簡單元素和復雜元素的概念&#xff0c;客戶程序可以像處理簡單元…

小米起訴“小米”商標侵權,索賠500萬!

近日浙江麗水有家叫小米的公司&#xff0c;因為商標侵權被小米科技起訴索賠500萬&#xff0c;需要變更企業名稱&#xff0c;官網也不能用“小米智能大家居”等&#xff0c;還有其它的賠償&#xff0c;普推知產商標老楊分析&#xff0c;“小米智能大家居”“小米”&#xff0c;后…

【Flask從入門到精通:第九課:數據庫基本操作、數據表操作以及數據操作】

數據庫操作 數據庫驅動&#xff08;drivers&#xff09;模塊&#xff1a;pymysql、MySQLDB 數據庫基本操作 在SQLAlchemy中&#xff0c;添加、修改、刪除操作&#xff0c;均由數據庫會話(sessionSM)管理。 會話用 db.session 表示。在準備把數據寫入數據庫前&#xff0c;要先…

交易平臺Zero Hash現已支持SUI交易

Zero Hash是一家領先的加密貨幣和穩定幣基礎設施平臺&#xff0c;為包括Stripe、Shift4和Franklin Templeton在內的公司提供支持&#xff0c;現在也支持對SUI的訪問。此舉使Zero Hash的客戶及其終端用戶能夠使用SUI。 提供API和SDK以及專注于無縫連接法幣、加密貨幣和穩定幣的…

讀人工智能全傳11人工智能會出什么錯

1. 人工智能會出什么錯 1.1. 一些報道是公正合理的&#xff0c;不過坦白地說&#xff0c;大部分報道都愚蠢得無可救藥 1.2. 一些報道頗有知識性和引導性&#xff0c;而大部分則是杞人憂天式的恐嚇 1.3. 滑稽的報道迎合了大眾對人工智能的“終結者式恐懼” 1.3.1. 我們創造出…

html設計(兩種常見的充電效果)

第一種 完整代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&…

方便快捷傳文件—搭建rsync文件傳輸服務器

比如我們有一個服務器&#xff0c;想把各個機器的文件都通過腳本傳給這臺機&#xff0c;用sftp或者直接rsync就必須輸密碼&#xff0c;肯定不行&#xff0c;做等效性免密又麻煩&#xff0c;怎么辦呢&#xff0c;這么辦&#xff01; 在服務端 yum -y install rsync #編輯&…

Vue3 關于scss預編譯中:deep 其中的deep如何理解

在SCSS預處理器中&#xff0c;:deep是一個偽類選擇器&#xff0c;用于選擇一個元素的所有后代元素&#xff0c;無論它們在DOM結構中的層級深度如何。換句話說&#xff0c;:deep選擇器是一個類似于CSS中的后代選擇器&#xff0c;但是它可以不考慮嵌套層級的限制&#xff0c;而是…