今天分享的題目來源于 LeetCode 上的劍指 Offer 系列 面試題09. 用兩個棧實作隊列。
題目連結:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
一、題目描述
用兩個棧實作一個隊列。隊列的聲明如下,請實作它的兩個函數
appendTail
和
deleteHead
,分别完成在隊列尾部插入整數和在隊列頭部删除整數的功能。(若隊列中沒有元素,
deleteHead
操作傳回
-1
)
示例 1:
輸入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
輸出:[null,null,3,-1]
示例 2:
輸入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
輸出:[null,-1,null,null,5,2]
提示:
-
1 <= values <= 10000
-
最多會對 appendTail、deleteHead 進行 10000 次調用
二、題目解析
實名吐槽這道題目的示例描述,我第一次真的沒有看懂是啥意思。。。。
我用大白話來翻譯一下 示例 2。
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
這個表示每一次操作的集合數組
[[],[],[5],[2],[],[]]
這個表示每一次操作後對應的參數的集合數組
1、CQueue
首先初始化,沒有參數,是以是
[]
,然後我們注意到
CQueue()
函數是沒有傳回值的,用 null 來表示(不要問我為什麼用 null 表示。。。)
2、deleteHead
删除操作,沒有參數,是以是
[]
,根據題意若隊列中沒有元素,
deleteHead
操作傳回
-1
,是以輸出值為
-1
。
3、appendTail
插入操作,有參數,此時是 5,并且
appendTail()
函數沒有傳回值的,用 null 來表示。
4、appendTail
插入操作,有參數,此時是 2,并且
appendTail()
函數沒有傳回值的,用 null 來表示。
5、deleteHead
删除操作,沒有參數,是以是
[]
,此時隊列中有元素,先進入的是 5,後進入的是 2,根據隊列 先進先出 的性質,元素 5 出列,是以傳回值是 5 。
6、deleteHead
删除操作,沒有參數,是以是
[]
,此時隊列中有元素,隻有元素 2,是以傳回值是 2 。
基本上看完上面的大白話翻譯就可以了解題意,解決問題也不難了。
入隊操作
如果是棧的插入操作,那我們可以把元素都先插入到 stack1 中,也就實作了隊列的 入隊操作 。
出隊操作
- 當 stack2 中不為空時,直接操作,此時在 stack2 中的棧頂元素是最先進入隊列的元素,傳回該元素即可;
- 如果 stack2 為空且 stack1 也為空,傳回 -1;
- 如果 stack2 為空且 stack1 不為空,首先需要把 stack1 中的元素逐個彈出并壓入到 stack2 中,然後傳回 stack2 的棧頂元素即可。
示例
三、動畫描述
四、圖檔描述
五、參考代碼
class CQueue {
LinkedList<Integer> stack1;
LinkedList<Integer> stack2;
public CQueue() {
// 初始化 stack1 與 stack2
stack1 = new LinkedList<Integer>();
stack2 = new LinkedList<Integer>();
}
public void appendTail(int value) {
// 直接将元素存放到 stack1 中
stack1.addLast(value);
}
public int deleteHead() {
// stack2 棧不為空,直接操作,傳回 stack2 的棧頂元素
if(!stack2.isEmpty()) {
return stack2.removeLast();
}
// 走到這一步的時候,stack2 是為空的狀态
// 根據題意,當 stack1 為空時,直接傳回 -1
if(stack1.isEmpty()){
return -1;
}
// 将 stack1 中的元素依次倒序放入 stack2 中
while(!stack1.isEmpty()){
stack2.addLast(stack1.removeLast());
}
// 傳回 stack2 的棧頂元素
return stack2.removeLast();
}
}
六、複雜度分析
插入元素操作
- 時間複雜度:O(N)。插入元素時,對于已有元素,每個元素都要彈出棧兩次,壓入棧兩次,是以是線性時間複雜度。
- 空間複雜度:O(N)。需要使用額外的空間存儲已有元素。
删除元素操作
- 時間複雜度:O(1)。判斷元素個數和删除隊列頭部元素都使用常數時間。
- 空間複雜度:O(1)。從第一個棧彈出一個元素,使用常數空間。
七、相關标簽
- 棧
- 隊列
由 五分鐘學算法 原班人馬打造的公衆号:圖解面試算法,現已正式上線!
接下來我們将會在該公衆号上,為大家分享優質的算法解題思路,堅持每天一篇原創文章的輸出,視訊動畫制作不易,感興趣的小夥伴可以關注點贊一下哈!