題目
用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 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 次調用
思路
解題思路:
棧無法實現隊列功能: 棧底元素(對應隊首元素)無法直接刪除,需要將上方所有元素出棧。
雙棧可實現列表倒序: 設有含三個元素的棧 A = [1,2,3] 和空棧 B = []。若循環執行 A 元素出棧並添加入棧 B ,直到棧 A爲空,則 A = [],B=[3,2,1] ,即 棧 B 元素實現棧 A 元素倒序 。
利用棧 B 刪除隊首元素: 倒序後,B 執行出棧則相當於刪除了 A 的棧底元素,即對應隊首元素。
函數設計:
題目只要求實現 加入隊尾appendTail() 和 刪除隊首deleteHead() 兩個函數的正常工作,因此我們可以設計棧 A 用於加入隊尾操作,棧 B 用於將元素倒序,從而實現刪除隊首元素。
加入隊尾 appendTail()函數: 將數字 val 加入棧 A 即可。
刪除隊首deleteHead()函數: 有以下三種情況。
當棧 B 不爲空: B中仍有已完成倒序的元素,因此直接返回 B 的棧頂元素。
否則,當 A 爲空: 即兩個棧都爲空,無元素,因此返回 -1 。
否則: 將棧 A 元素全部轉移至棧 B 中,實現元素倒序,並返回棧 B 的棧頂元素。
複雜度分析:
由於問題特殊,以下分析僅滿足添加 N 個元素並刪除 N 個元素,即棧初始和結束狀態下都爲空的情況。
時間複雜度: appendTail()函數爲 O(1);deleteHead() 函數在 N 次隊首元素刪除操作中總共需完成 N 個元素的倒序。
空間複雜度 O(N) : 最差情況下,棧 A 和 B 共保存 N 個元素。
代碼
class CQueue {
stack<int> st1;
stack<int> st2;
public:
CQueue() {
}
void appendTail(int value) {
st1.push(value);
}
int deleteHead() {
int res = -1;
if (st1.empty() && st2.empty()) {
return res;
}
if (st2.empty()) {
while (!st1.empty()) {
st2.push(st1.top());
st1.pop();
}
}
res = st2.top();
st2.pop();
return res;
}
};