Queue & Stack Conclusion
本文蒐集
LeetCode 225: Implement Queue using Stacks
Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push
, peek
, pop
, and empty
).
Implement the MyQueue
class:
void push(int x)
Pushes element x to the back of the queue.int pop()
Removes the element from the front of the queue and returns it.int peek()
Returns the element at the front of the queue.boolean empty()
Returnstrue
if the queue is empty,false
otherwise.
Notes:
- You must use only standard operations of a stack, which means only
push to top
,peek/pop from top
,size
, andis empty
operations are valid. - Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack's standard operations.
Follow-up: Can you implement the queue such that each operation is amortized O(1)
time complexity? In other words, performing n
operations will take overall O(n)
time even if one of those operations may take longer.
Example 1:
Input
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]
Explanation
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
Constraints:
1 <= x <= 9
- At most
100
calls will be made topush
,pop
,peek
, andempty
. - All the calls to
pop
andpeek
are valid.
我的解法
class MyQueue:
def __init__(self):
"""
Initialize your data structure here.
"""
self.stack1 = []
self.stack2 = []
def push(self, x: int) -> None:
"""
Push element x to the back of queue.
"""
self.stack1.append(x)
def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if self.stack2:
return self.stack2.pop()
while self.stack1:
self.stack2.append(self.stack1.pop())
if self.stack2:
return self.stack2.pop()
return 0
def peek(self) -> int:
"""
Get the front element.
"""
if self.stack2:
return self.stack2[-1]
while self.stack1:
self.stack2.append(self.stack1.pop())
if self.stack2:
return self.stack2[-1]
return 0
def empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
if self.stack1 or self.stack2:
return False
return True
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
LeetCode 232: Implement Stack using Queues
Implement a last in first out (LIFO) stack using only two queues. The implemented stack should support all the functions of a normal queue (push
, top
, pop
, and empty
).
Implement the MyStack
class:
void push(int x)
Pushes element x to the top of the stack.int pop()
Removes the element on the top of the stack and returns it.int top()
Returns the element on the top of the stack.boolean empty()
Returnstrue
if the stack is empty,false
otherwise.
Notes:
- You must use only standard operations of a queue, which means only
push to back
,peek/pop from front
,size
, andis empty
operations are valid. - Depending on your language, the queue may not be supported natively. You may simulate a queue using a list or deque (double-ended queue), as long as you use only a queue's standard operations.
Example 1:
Input
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output
[null, null, null, 2, 2, false]
Explanation
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // return 2
myStack.pop(); // return 2
myStack.empty(); // return False
Constraints:
1 <= x <= 9
- At most
100
calls will be made topush
,pop
,top
, andempty
. - All the calls to
pop
andtop
are valid.
Follow-up: Can you implement the stack such that each operation is amortized O(1)
time complexity? In other words, performing n
operations will take overall O(n)
time even if one of those operations may take longer. You can use more than two queues.
我的解法
class MyStack:
def __init__(self):
"""
Initialize your data structure here.
"""
self.queue1 = []
self.queue2 = []
def push(self, x: int) -> None:
"""
Push element x onto stack.
"""
if self.empty():
self.queue1.append(x)
elif self.queue1:
self.queue2.append(x)
while self.queue1:
self.queue2.append(self.queue1.pop(0))
else:
self.queue1.append(x)
while self.queue2:
self.queue1.append(self.queue2.pop(0))
def pop(self) -> int:
"""
Removes the element on top of the stack and returns that element.
"""
if self.empty():
return 0
elif self.queue1:
return self.queue1.pop(0)
else:
return self.queue2.pop(0)
def top(self) -> int:
"""
Get the top element.
"""
if self.empty():
return 0
elif self.queue1:
return self.queue1[0]
else:
return self.queue2[0]
def empty(self) -> bool:
"""
Returns whether the stack is empty.
"""
if self.queue1 or self.queue2:
return False
return True
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()
LeetCode 394: Decode String
Given an encoded string, return its decoded string.
The encoding rule is: k[encoded_string]
, where the encoded_string
inside the square brackets is being repeated exactly k
times. Note that k
is guaranteed to be a positive integer.
You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.
Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k
. For example, there won't be input like 3a
or 2[4]
.
Example 1:
Input: s = "3[a]2[bc]"
Output: "aaabcbc"
Example 2: Input: s = "3[a2[c]]"
Output: "accaccacc"
Example 3: Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"
Example 4: Input: s = "abc3[cd]xyz"
Output: "abccdcdcdxyz"
Constraints:
1 <= s.length <= 30
s
consists of lowercase English letters, digits, and square brackets'[]'
.s
is guaranteed to be a valid input.- All the integers in
s
are in the range[1, 300]
.
我的解法
class Solution:
def decodeString(self, s: str) -> str:
stack = []
temp = []
result = ''
number = ''
for i in s:
if i == ']':
c = stack.pop()
while c != '[':
temp.append(c)
c = stack.pop()
number = stack.pop()
try:
while True:
number = str(int(stack[-1])) + number
stack.pop()
except:
temp *= int(number)
while temp:
stack.append(temp.pop())
else:
stack.append(i)
for _ in stack:
result = result + _
return result
LeetCode 733: Flood Fill
An image
is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).
Given a coordinate (sr, sc)
representing the starting pixel (row and column) of the flood fill, and a pixel value newColor
, "flood fill" the image.
To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. Replace the color of all of the aforementioned pixels with the newColor.
At the end, return the modified image.
Example 1:
Input:
image = [[1,1,1],[1,1,0],[1,0,1]]
sr = 1, sc = 1, newColor = 2
Output: [[2,2,2],[2,2,0],[2,0,1]]
Explanation:
From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected
by a path of the same color as the starting pixel are colored with the new color.
Note the bottom corner is not colored 2, because it is not 4-directionally connected
to the starting pixel.
Note:
- The length of
image
andimage[0]
will be in the range[1, 50]
. - The given starting pixel will satisfy
0 <= sr < image.length
and0 <= sc < image[0].length
. - The value of each color in
image[i][j]
andnewColor
will be an integer in[0, 65535]
.
我的解法
class Solution:
def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:
self.visited = set()
self.newColor = newColor
self.oldColor = image[sr][sc]
self.dfs(image, sr, sc)
return image
def dfs(self, image: List[List[int]], sr: int, sc: int):
if sr < 0 or sc < 0 or sr >= len(image) or sc >= len(image[0]) or image[sr][sc] != self.oldColor or (sr,sc) in self.visited:
return
image[sr][sc] = self.newColor
self.visited.add((sr, sc))
self.dfs(image, sr-1, sc)
self.dfs(image, sr+1, sc)
self.dfs(image, sr, sc-1)
self.dfs(image, sr, sc+1)
LeetCode 542: 01 Matrix
Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.
The distance between two adjacent cells is 1.
Example 1:
Input:
[[0,0,0],
[0,1,0],
[0,0,0]]
Output:
[[0,0,0],
[0,1,0],
[0,0,0]]
Example 2: Input:
[[0,0,0],
[0,1,0],
[1,1,1]]
Output:
[[0,0,0],
[0,1,0],
[1,2,1]]
Note:
- The number of elements of the given matrix will not exceed 10,000.
- There are at least one 0 in the given matrix.
- The cells are adjacent in only four directions: up, down, left and right.
我的解法 1
利用 DFS ,但是會 Time Limit Exceeded
# Time Limit Exceeded
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == 1:
matrix[i][j] = float('inf')
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == 0:
self.dfs(matrix, i, j, 0)
return matrix
def dfs(self, m, i, j, count):
if i < 0 or i >= len(m) or j < 0 or j >= len(m[0]) or count > m[i][j]:
return
m[i][j] = count
count += 1
self.dfs(m, i+1, j, count)
self.dfs(m, i-1, j, count)
self.dfs(m, i, j+1, count)
self.dfs(m, i, j-1, count)
我的解法 2
參考網友的 BFS1,大部分過程有想到但是一開始就把所有 0 加入 queue
卻沒想到~
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
m, n = len(matrix), len(matrix[0])
queue = collections.deque()
res = [[-1 for _ in range(n)] for _ in range(m)]
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
res[i][j] = 0
queue.append((i, j))
while queue:
curI, curJ = queue.popleft()
for i, j in dirs:
neighBorI, neighBorJ = curI + i, curJ + j
if 0 <= neighBorI < m and 0 <= neighBorJ < n and res[neighBorI][neighBorJ] == -1:
res[neighBorI][neighBorJ] = res[curI][curJ] + 1
queue.append((neighBorI, neighBorJ))
return res
## 我的解法 3 很美的解法 自己是有寫出上半段(左上到右下),但是也沒想到再一次右下到左上
可以彌補沒找到的方向 class Solution:
def updateMatrix(self, matrix):
m, n = len(matrix), len(matrix and matrix[0])
for i in range(m):
for j in range(n):
if matrix[i][j] != 0:
matrix[i][j] = float("inf")
if i > 0 and matrix[i - 1][j] + 1 < matrix[i][j]:
matrix[i][j] = matrix[i - 1][j] + 1
if j > 0 and matrix[i][j - 1] + 1 < matrix[i][j]:
matrix[i][j] = matrix[i][j - 1] + 1
for i in range(m - 1, -1, -1):
for j in range(n - 1, -1, -1):
if matrix[i][j] != 0:
if i + 1 < m and matrix[i + 1][j] + 1 < matrix[i][j]:
matrix[i][j] = matrix[i + 1][j] + 1
if j + 1 < n and matrix[i][j + 1] + 1 < matrix[i][j]:
matrix[i][j] = matrix[i][j + 1] + 1
return matrix
# LeetCode 841: Keys and Rooms There are N
rooms and you start in room 0
. Each room has a distinct number in 0, 1, 2, ..., N-1
, and each room may have some keys to access the next room.
Formally, each room i
has a list of keys rooms[i]
, and each key rooms[i][j]
is an integer in [0, 1, ..., N-1]
where N = rooms.length
. A key rooms[i][j] = v
opens the room with number v
.
Initially, all the rooms start locked (except for room 0
).
You can walk back and forth between rooms freely.
Return true
if and only if you can enter every room.
Example 1:
Input: [[1],[2],[3],[]]
Output: true
Explanation:
We start in room 0, and pick up key 1.
We then go to room 1, and pick up key 2.
We then go to room 2, and pick up key 3.
We then go to room 3. Since we were able to go to every room, we return true.
Example 2: Input: [[1,3],[3,0,1],[2],[0]]
Output: false
Explanation: We can't enter the room with number 2.
Note:
1 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
- The number of keys in all rooms combined is at most
3000
.
我的解法
class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
queue = []
visited = set()
queue.append(0)
visited.add(0)
while queue:
length = len(queue)
for _ in range(length):
i = queue.pop(0)
for j in rooms[i]:
if j not in visited:
queue.append(j)
visited.add(j)
if len(visited) == len(rooms):
return True
else:
return False