原題LeetCode鏈接:劍指Offer09. 用兩個棧實現隊列
題目:用兩個棧實現隊列
用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 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 次調用
思路
棧具有“後進先出”的特性,隊列具有“先進先出”的特性。
題目要求是使用兩個棧,我們假設它們分別是s1,s2。棧本身和隊列一樣也是一種順序結構,不考慮操作的話其實隊列與棧它們內部的元素順序是相同的。所以向一個棧中插入數據的操作就可以當作隊列的插入操作。
那麼我們可以主要使用s1來實現,s2作爲輔助結構。
當向s1中插入數據時,元素順序與插入隊列的順序一致,故可以當做是隊列的插入元素操作。
要想做到隊列的刪除,就不能簡單地彈出棧中元素。“先進後出,後進先出”,組合一起就是“先進先出”。我們可以用s2來輔助顛倒一次,即從s1中彈出後立即進入s2。如下圖:
這樣,彈出s2中的’6’就相當於隊列的隊首出隊。以上就實現了隊列的插入和刪除功能,最後別忘了將s2中的元素再插入回s1。
C++代碼
class CQueue {
public:
stack<int> s1, s2;
//在s1插入
CQueue() {
}
void appendTail(int value) {
s1.push(value);
}
int deleteHead() {
if(s1.empty()) return -1;
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int res = s2.top();
s2.pop();
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
複雜度分析:
時間複雜度
:插入元素就是直接插入即可,時間複雜度就是O(1);刪除元素的話需要對所有元素進行兩次轉移,時間複雜度就是O(n)。
空間複雜度
:插入元素僅在s1上,沒用到s2,空間複雜度是O(1).刪除元素時用到兩s2,空間複雜度O(n)。