題目
棧和隊列是常見的數據結構,隊列的特點是 先進先出
,而棧的特點是 先進後出
。
請使用 隊列 模擬實現棧的下列操作:
- push(x) -- 將元素 x 壓入棧頂
- pop() -- 移除並返回棧頂元素
- top() -- 獲取棧頂元素
- empty() -- 判斷棧是否爲空
說明:
- 可以用 列表list 來模擬隊列,但只允許使用隊列的基本操作。
- 假設每次調用 pop 和 top 都能保證棧不爲空。
實現思路
- 使用兩個隊列,一個作爲實際隊列 queue1 ,另一個作爲臨時隊列 queue2
- 每次 push 入棧操作,直接把 待入棧的新元素 添加到 queue1 的隊尾即可
- 每次 pop 出棧操作,需要循環對 queue1 執行出隊操作,並把出隊的元素依次添加到 queue2 的隊尾(最後一個出隊的元素不添加),接着再反過來操作,循環對 queue2 執行出隊操作,並把出隊的元素依次添加到 queue1 的隊尾
- 每次 top 獲取棧頂元素操作,可以複用出棧操作的實現(但要記得把出棧元素重新添加到queue1),從而拿到棧頂的元素
- 每次 empty 操作,只需判斷 queue1 是否爲空
代碼實現
class MyStack:
def __init__(self):
self.queue1 = [] # 實際隊列
self.queue2 = [] # 臨時隊列
def push(self, x):
self.queue1.append(x)
def pop(self):
while len(self.queue1) > 1:
self.queue2.append(self.queue1.pop(0))
res = self.queue1.pop(0)
while self.queue2:
self.queue1.append(self.queue2.pop(0))
return res
def top(self):
res = self.pop()
self.queue1.append(res)
return res
def empty(self):
return self.queue1 == []
上面方法使用了兩個隊列來實現,那麼如果限制只能使用一個隊列的話,又該要如何優化實現呢?
其實並不難,我們只需在模擬出棧操作時,將隊頭的元素(除了最後一個元素外),依次執行出隊操作,並重新添加到隊尾,這樣一來只需要使用一個隊列即可實現棧的操作。
優化後的代碼實現
class MyStack:
def __init__(self):
self.queue1 = []
def push(self, x):
self.queue1.append(x)
def pop(self):
len1 = len(self.queue1)
while len1 > 1:
self.queue1.append(self.queue1.pop(0))
len1 -= 1
return self.queue1.pop(0)
def top(self):
res = self.pop()
self.queue1.append(res)
return res
def empty(self):
return self.queue1 == []