算法面试:栈实现队列的方案
前言:Java數據結構與算法專題會不定時更新,歡迎各位讀者監督。本篇文章介紹一個有趣的問題:用兩個棧實現一個隊列。這道題來自互聯網公司的算法面試,作為一道經典的算法面試題,本文給出問題的解決思路和Java實現代碼。
前兩篇文章介紹了棧(stack)和隊列(queue)兩種特殊的數據結構和他們特點,棧和隊列雖然是特點針鋒相對的,但有意思的是他們卻彼此相互聯系。
后進先出的棧如何才能實現先進先出的隊列呢?一般會用兩個棧來實現。首先定義兩個棧分別為stack1和stack2.
1.解決方案一:
我們讓入隊的操作在stack1中完成,出隊的操作在stack2中完成,具體分析過程如下:
- 入隊: ①將所有元素直接向stack1中壓棧
- 出隊: ②將stack1中的所有元素依次出棧,③緊接著入棧到stack2中,④然后彈出stack2中的元素。
為清楚說明,用下圖解釋:
來回入隊、出隊比較麻煩,尤其是出隊比較麻煩,需要先將元素從stack1倒入stack2中,然后stack2彈出的元素又倒回到stack1中。有沒有更優化的方案呢?以下方案2是改進之后的思路。
2.解決方案二:
入隊都在stack1中進行,stack2用于隊列,同時保證所有元素都在一個棧里,且遵循以下約束:
- 入隊:不管stack1空與否,都將stack2中的所有元素壓入stack1中
- 出隊:若stack2中不為空,則直接從stack2中彈出元素;若stack2為空,則說明隊列為空,不能出隊。
方案2與方案1的區別在于,方案2中把倒回的操作放在了入隊中完成,使連續入隊、出隊的效率提高。有沒有更優化的方案呢?以下對方案2改進,給出方案3.
3.解決方案三:
入隊都在stack1中完成,出隊都在stack2中完成,且遵循以下約束:
- 入隊:直接把元素壓入stack1中;
- 出隊:若stack2中不為空,則直接彈出stack2中的元素;若stack2中為空,則將stack1中的所有元素倒入stack2中,然后彈出stack2的棧頂元素。同樣,若兩個棧都為空,則隊列為空隊,無法出隊。
方案3的特點是:入隊時非常簡單,而在出隊時,多數情況下可以直接通過彈出stack2完成。如果把stack1中的元素倒入stack2中,則一般不用每次都進行這樣的操作。最壞的情況就是出隊一個元素、入隊一個元素這樣的循環,導致每次出隊都需要轉移元素。
4.java代碼實現
以下給出方案3的代碼實現:
public class Stacks2Queue {private Stack stack1;private Stack stack2;private int maxLength;public Stacks2Queue(int capacity){maxLength = capacity;stack1 = new Stack(capacity); stack2 = new Stack(capacity); }/*** 隊列入隊* @param element 入隊元素* @return 入隊成功?*/public boolean put(int element){if(stack1.isFull() || maxLength == stack1.getSize()){//此時stack1滿return false;}stack1.push(element);return true;}/*** 隊列出隊* @return 出隊的元素*/public int poll(){if(!stack2.isEmpty()){return stack2.pop();}else{while(!stack1.isEmpty()){stack2.push(stack1.pop());}return stack2.pop();}}/*** 求隊列長度* @return 返回隊列長度*/public int getSize(){return stack1.getSize()+stack2.getSize();} }測試代碼如下:
public class Stack2QueueTest {public static void main(String[] args) {Stacks2Queue q = new Stacks2Queue(5);q.put(1); //入隊元素 1q.put(2); //入隊元素 2System.out.println("出隊的元素為"+q.poll()); //出隊元素 打印1System.out.println("此時隊列長度為"+q.getSize()); //返回1q.put(3); //入隊元素 3q.put(4); //入隊元素 4System.out.println("出隊的元素為"+q.poll()); //出隊元素 打印2System.out.println("出隊的元素為"+q.poll()); //出隊元素 打印3 本次出隊操作會把3和4兩個元素從stack1中倒入stack2中} }注:以上代碼用到了堆和棧的代碼,請移步到前兩篇文章獲取Java數據結構與算法——棧(stack)和Java數據結構與算法——隊列(queue)
5.小結:
本文介紹了一個互聯網面試經典問題如何用兩個棧實現隊列?并給出解決思路和java代碼實現,后續會給出其姊妹篇如何用兩個隊列實現棧?的問題。
歡迎下方討論提問,覺得文章對您有用,請收藏點個贊 ^_^
總結
以上是生活随笔為你收集整理的算法面试:栈实现队列的方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 物联网有哪些技术 物联网跟云计算人工智能
- 下一篇: 19号以后包括数组在内的所有内容(数组、