栈是先入后出(后入先出)的数据结构,常用操作就 push 和 pop,Python中用列表实现即可,基本概念可以看Leetbook相关章节。
155. 最小栈(剑指 Offer 30. 包含min函数的栈)
class MinStack:
def __init__(self):
self.stack = [(0, float('+inf'))]
def push(self, x: int) -> None:
self.stack.append((x, min(self.stack[-1][1], x)))
def pop(self) -> None:
self.stack.pop()
def top(self) -> int:
return self.stack[-1][0]
def getMin(self) -> int:
return self.stack[-1][1]
实现最小栈的关键就是要用辅助栈记录每次 push 操作时的最小值,这样栈值在递增时,最小值永远是第一个值(如 [1, 2, 3, 4] 对应 [1, 1, 1, 1]);在递减时,最小值永远是当前值(如 [4, 3, 2, 1] 对应 [4, 3, 2, 1])。
class Solution:
def isValid(self, s: str) -> bool:
stack = []
for char in s:
if char == '(' or char == '[' or char == '{':
stack.append(char)
else:
if stack == []:
return False
else:
pre = stack.pop()
if (char == ')' and pre != '(') or (char == ']' and pre != '[') or (char == '}' and pre != '{'):
return False
return True if stack == [] else False
分类讨论:如果是三个左括号之一,就 push 进入栈;如果是三个右括号之一,就检查栈顶,若栈顶为空就肯定不匹配,不为空则考察弹出的栈顶元素,若不是对应的左括号则返回 False。最后如果还有左括号(栈非空),也返回 False。
946. 验证栈序列(剑指 Offer 31. 栈的压入、弹出序列)
class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
pop_pointer = 0
stack = []
for num in pushed:
stack.append(num)
while stack and pop_pointer < len(popped) and stack[-1] == popped[pop_pointer]:
stack.pop()
pop_pointer += 1
return pop_pointer == len(popped)
用指针记录 popped 序列,然后逐个把 pushed 序列的元素 push 进入栈中,如果出现相同值,则弹出栈顶元素,同时指针右移1位,如果所有元素都能pop 则返回 True。
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
length = len(temperatures)
ans = [0] * length
stack = []
for i in range(length):
temperature = temperatures[i]
# 如果第i天的温度大于前面某天的温度
while stack and temperature > temperatures[stack[-1]]:
prev_index = stack.pop() # 前面某天的下标
ans[prev_index] = i - prev_index # ans中前面某天的答案即天数
# 记录第i天的温度
stack.append(i)
return ans
遍历每一天的温度,用一个栈记录每天的温度下标,当遍历到第 i 天时,比较第 i 天是否大于前面某天的温度,如果是则弹出该天(已找到答案),并在 ans 数组中记录下天数(差值)。