def nextGreaterElements(self, nums: List[int]) -> List[int]: """ 核心: 1.单调栈 2.利用取模运算(%)获得环形特效,解决环形数组 """ monotonous_stack = Stack() nums_len = len(nums) res_lis = [-1] * nums_len # 将 nums2 的所有元素,倒序入单调栈 for i in range(nums_len * 2 - 1, -1, -1): index = i % nums_len # 1.维护单调栈 while not monotonous_stack.is_empty( ) and nums[index] >= monotonous_stack.peek(): monotonous_stack.pop() # 2.利用栈 res_lis[index] = monotonous_stack.peek() if monotonous_stack.peek( ) is not None else -1 # 3.单调栈入栈 monotonous_stack.push(nums[index]) return res_lis
def reverseStack(self, s: Stack) -> Stack: # 递归边界 if s.is_empty() or s.size == 1: return s # 将底部元素移到顶部 self.move_bottom_to_top(s) # 该栈 pop 出一个元素并记录在 top 中,形成子栈,并递归调用翻转方法 top = s.pop() s = self.reverseStack(s) # 翻转后的子栈,push 原来的 top 元素 s.push(top) return s
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: """核心:单调栈""" monotonous_stack = Stack() # 单调栈,单调递减 memory_dic = {} # 将 nums2 的所有元素,倒序入单调栈 for i in range(len(nums2) - 1, -1, -1): # 1.维护单调栈--[将单调栈中 <= 当前元素(nums2[i])的元素,全部 pop 出去] while not monotonous_stack.is_empty( ) and nums2[i] >= monotonous_stack.peek(): monotonous_stack.pop() # 2.使用单调栈--[根据单调栈的栈顶元素(stack.peek()),获取值] memory_dic[nums2[i]] = -1 if monotonous_stack.is_empty( ) else monotonous_stack.peek() # 3.元素入栈 monotonous_stack.push(nums2[i]) return [memory_dic.get(item) for item in nums1]
def dailyTemperatures(self, T: List[int]) -> List[int]: """ 核心: 1.单调栈 2.单调栈记录特殊数组 [val, index] :param T: :return: """ t_len = len(T) res_lis = [0] * t_len stack = Stack() # stack 记录特殊数组 [值, 位置index] for i in range(t_len - 1, -1, -1): # 1.维护单调栈 while not stack.is_empty() and T[i] >= stack.peek()[0]: stack.pop() # 2.利用单调栈 res_lis[i] = 0 if stack.peek() is None else stack.peek()[1] - i # 3.元素 push 进入单调栈 stack.push([T[i], i]) return res_lis
def __init__(self): self.s1 = Stack() # 用于入队 self.s2 = Stack() # 用于出队
class MyQueue: """核心:使用两个栈,分别主要用于入队、出队""" def __init__(self): self.s1 = Stack() # 用于入队 self.s2 = Stack() # 用于出队 def moves_items(self): """pop all items form s1 and push them to s2""" while not self.s1.is_empty(): self.s2.push(self.s1.pop()) def push(self, x: int) -> None: self.s1.push(x) def pop(self) -> int: if self.s2.is_empty(): self.moves_items() return self.s2.pop() def peek(self) -> int: if self.s2.is_empty(): self.moves_items() return self.s2.peek() def empty(self) -> bool: return self.s1.is_empty() and self.s2.is_empty()
@staticmethod def move_bottom_to_top(s: Stack): s.items.append(s.items.pop(0)) def reverseStack(self, s: Stack) -> Stack: # 递归边界 if s.is_empty() or s.size == 1: return s # 将底部元素移到顶部 self.move_bottom_to_top(s) # 该栈 pop 出一个元素并记录在 top 中,形成子栈,并递归调用翻转方法 top = s.pop() s = self.reverseStack(s) # 翻转后的子栈,push 原来的 top 元素 s.push(top) return s if __name__ == "__main__": solution = Solution() stack = Stack() for i in range(5): stack.push(i) stack = solution.reverseStack(stack) for i in range(10): print(stack.pop()) pass
def largestRectangleArea(self, heights: List[int]) -> int: """ 单调栈(单增): 保持栈顶为当前栈最大元素 我们在缓存数据的时候,是从左向右缓存的, 我们计算出一个结果的顺序是从右向左的,并且计算完成以后我们就不再需要了, 符合后进先出的特点。因此,我们需要的这个作为缓存的数据结构就是栈。 """ lis_len = len(heights) max_area = 0 stack = Stack() for i in range(lis_len): while not stack.is_empty() and heights[i] < stack.peek()[1]: index, cur_height = stack.pop() # 处理相等的特殊情况 while not stack.is_empty() and heights[i] == stack.peek(): stack.pop() if stack.is_empty(): cur_width = i else: cur_width = i - stack.peek()[0] - 1 max_area = max(max_area, cur_height * cur_width) stack.push([i, heights[i]]) while not stack.is_empty(): index, cur_height = stack.pop() while not stack.is_empty() and cur_height == stack.peek()[1]: stack.pop() if stack.is_empty(): cur_width = lis_len else: cur_width = lis_len - stack.peek()[0] - 1 max_area = max(max_area, cur_height * cur_width) return max_area
def __init__(self): self._stack = Stack() self._min_stack = Stack() # 使用辅助栈,来记录当前最小值
class MinStack: def __init__(self): self._stack = Stack() self._min_stack = Stack() # 使用辅助栈,来记录当前最小值 def push(self, x: int) -> None: self._stack.push(x) # min_stack push 当前栈最小值 if self._min_stack.peek() is None: self._min_stack.push(x) else: self._min_stack.push(min(x, self._min_stack.peek())) def pop(self) -> None: self._stack.pop() self._min_stack.pop() def top(self) -> int: return self._stack.peek() def getMin(self) -> int: return self._min_stack.peek()