# [未完成] 使用Queue實現Stack的3種方法 (Leetcode 225) > 寫每日一題的時候發現這題好像在哪間學校的考古題寫過,感覺蠻有機會考出來,就把所有思路都記錄下來,萬一考出來了? `[112交大]` > 考試時可能還要注意 $isFull()$ 的情況。 [ToC] | LeetCode | 力扣 | | -------- | -------- | | [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) | [225. 用队列实现栈](https://leetcode.cn/problems/implement-stack-using-queues/) ## Python的deque套件簡介 依照題目的要求,能使用那些函數,且python中是如何調用的 $back()$ ? -> X [未完成] ## Method 1. 使用兩個queue,在 push() 時調整 - 目的為**使queue1維持stack的性質** (即queue1的第1個元素為stack上最頂端的元素,以此類推),queue2用來在調整時暫存queue1的元素 - 時間複雜度: - $push()$: $O(n)$ - $pop()$: $O(1)$ - $top()$: $O(1)$ - $empty()$: $O(1)$ - 在上述的前提下,可以發現在stack的4個操作裡面,只有 $push()$ 會破壞這個性質,因此我們要在 $push()$ 的時候做調整。 - 在 $push()$ 時,因為queue1本身就具stack的性質,為了繼續維持stack性質,可以先先把新的元素push到queue2,這樣新的元素在queue2中就會是stack最頂層的元素。 - 之後再把原本queue1內的元素依次加入queue2中 (pop出來後push進queue2),queue2就會維持stack的性質,最後再把queue1和queue2兩者交換,讓queue1繼續維持stack的性質就好。 ```python= from collections import deque class MyStack1: def __init__(self): self.queue1 = deque() self.queue2 = deque() def push(self, x: int) -> None: """ 因為queue1要保持stack的性質,所以要把queue1的元素都移到queue2 那麼queue2的元素就會維持stack的性質,最後再把兩者交換,讓queue1維持stack的性質 """ self.queue2.append(x) while self.queue1: self.queue2.append(self.queue1.popleft()) self.queue1, self.queue2 = self.queue2, self.queue1 def pop(self) -> int: """ 在某些語言中的pop()可能不能處理size為0的情況,考試時要注意 """ return self.queue1.popleft() if self.queue1 else None def top(self) -> int: """ Python的deque沒有top(),直接取[0]就好,另外和pop()相同,在某些語言中的top()可能不能處理size為0的情況,考試時要注意 """ return self.queue1[0] if self.queue1 else None def empty(self) -> bool: return not self.queue1 ``` ## Method 2. 使用兩個queue,在 pop() 時調整 - 目的為**使queue1還是維持queue的性質**,queue2同樣用來在調整時暫存queue1的元素 - 時間複雜度: - $push()$: $O(1)$ - $pop()$: $O(n)$ - $top()$: $O(n)$ - $empty()$: $O(1)$ - 在上述的前提下,可以發現在stack的4個操作裡面,其實都不會破壞這個性質。 - 但在 $pop()$ 時因為我們不能直接取出和刪除最後一個元素,所以我們要利用暫存用的queue2,先對queue1做n-1次pop,同時把元素push到queue2後,再對queue1做1次pop把最後一個元素pop出來,這個元素就是stack頂端的元素。最後再把兩個queue交換,讓queue1維持原本的性質。 - 在做 $top()$ 時我們同樣不能直接取出最後一個元素,但我們可以利用已經寫好的 $pop()$ ,把頂端的元素pop出來,再把它push回去就好。 - 有些題解在取 $top()$ 時的的方法是用了 $back()$ ,但是這樣就不是queue了,不符合題目要求。 ```python= class MyStack2: def __init__(self): self.queue1 = deque() self.queue2 = deque() def push(self, x: int) -> None: self.queue1.append(x) def pop(self) -> int: if not self.queue1: return None size = len(self.queue1) while size > 1: self.queue2.append(self.queue1.popleft()) size -= 1 self.queue1, self.queue2 = self.queue2, self.queue1 return self.queue2.popleft() def top(self) -> int: """ 這裡可以用上述的pop()方法把top的元素pop出來,再把它push回去就好了 """ if not self.queue1: return None top = self.pop() self.push(top) return top def empty(self) -> bool: return not self.queue1 ``` ## Method 3. 使用一個queue,在 pop() 時調整 - 和方法2.類似,但是不用兩個queue,而是只用一個queue就能完成 - 使queue1還是維持queue的性質,但**不用使用另外一個queue2暫存queue1的元素,直接push回queue1即可** - 時間複雜度: - $push()$: $O(1)$ - $pop()$: $O(n)$ - $top()$: $O(n)$ - $empty()$: $O(1)$ - 概念和方法2.基本相同,因此不再贅述。 ```python= class MyStack3: def __init__(self): self.queue = deque() def push(self, x: int) -> None: self.queue.append(x) def pop(self) -> int: if not self.queue: return None size = len(self.queue) while size > 1: self.queue.append(self.queue.popleft()) size -= 1 return self.queue.popleft() def top(self) -> int: """ 這裡可以用上述的pop()方法把top的元素pop出來,再把它push回去就好了 """ if not self.queue: return None top = self.pop() self.push(top) return top def empty(self) -> bool: return not self.queue class MyStack(MyStack3): pass ```
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.