Implementing Queues with Stacks and Stacks with Queues
Implementing a Queue Using Two Stacks
class QueueWithStacks:
def __init__(self):
self.input_stack = []
self.output_stack = []
def enqueue(self, value: int) -> None:
self.input_stack.append(value)
def dequeue(self) -> int:
if self.is_empty():
return None
if self.output_stack:
return self.output_stack.pop()
else:
while self.input_stack:
self.output_stack.append(self.input_stack.pop())
return self.output_stack.pop()
def peek(self) -> int:
result = self.dequeue()
self.output_stack.append(result)
return result
def is_empty(self) -> bool:
return not (self.input_stack or self.output_stack)
This approach uses two stacks to simulate queue operations. Elements are first pushed onto the input stack. When dequeuing, if the output stack is empty, all elements from the input stack are transferred to the output stack in reverse order, allowing to FIFO behavior.
Implementing a Stack Using a Single Queue
from collections import deque
class StackWithQueue:
def __init__(self):
self.data_queue = deque()
def push(self, value: int) -> None:
self.data_queue.append(value)
def pop(self) -> int:
if self.is_empty():
return None
for _ in range(len(self.data_queue) - 1):
self.data_queue.append(self.data_queue.popleft())
return self.data_queue.popleft()
def top(self) -> int:
if self.is_empty():
return None
return self.data_queue[-1]
def is_empty(self) -> bool:
return not self.data_queue
This implementation uses a single queue to achieve stack behavior. When poppping, all elements except the last are cycled through the queue, effectively making the last element accessible for removal, thus maintaining LIFO order.
Validating Parentheses with a Stack
class ParenthesesValidator:
def is_valid(self, expression: str) -> bool:
bracket_stack = []
pairs = {'[': ']', '{': '}', '(': ')'}
for char in expression:
if char in pairs:
bracket_stack.append(char)
else:
if not bracket_stack or pairs[bracket_stack[-1]] != char:
return False
bracket_stack.pop()
return len(bracket_stack) == 0
This solution checks for balanecd parentheses by pushing opening brackets onto a stack and verifying matching closing brackets when encountered.
Removing Adjacent Duplicates Using a Stack
class DuplicateRemover:
def remove_adjacent_duplicates(self, text: str) -> str:
result = []
for char in text:
if not result or char != result[-1]:
result.append(char)
else:
result.pop()
return ''.join(result)
This approach processes each character, adding it to the result list only if it doesn't match the last character in the list, effectively removing all adjacent duplicates.