1138 words
6 minutes
日拱两卒(四)
2026-07-18
70
最小栈。让栈能额外支持一个操作,返回栈内最小值。
栈内多维护一个“前缀最小值”即可。
class MinStack:
def __init__(self): self.stack = [(0, float("inf"))]
def push(self, value: int) -> None: self.stack.append((value, min(self.stack[-1][1], value)))
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]69
有效的括号。
给一个含有三种括号的序列,判断是否合法。
class Solution: def isValid(self, s: str) -> bool: stack = [] need = { "}" : "{", "]" : "[", ")" : "(" } for c in s: if c == '(' or c == '[' or c == '{': stack.append(c) else: if not stack: return False if stack[-1] != need[c]: return False stack.pop() return not stack68
寻找两个正序数组的中位数。
类似快速选择每次丢一半的思想。
class Solution: def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: def findkth(k): start1 = 0 start2 = 0 while True: if start1 == len(nums1): return nums2[start2 + k - 1] if start2 == len(nums2): return nums1[start1 + k - 1] if k == 1: return min(nums1[start1], nums2[start2]) half = k // 2 idx1 = min(start1 + half, len(nums1)) - 1 idx2 = min(start2 + half, len(nums2)) - 1 if nums1[idx1] < nums2[idx2]: k -= idx1 - start1 + 1 start1 = idx1 + 1 else: k -= idx2 - start2 + 1 start2 = idx2 + 1
total = len(nums1) + len(nums2) if total & 1: return findkth((1 + total) >> 1) else: left = findkth(total >> 1) right = findkth((total >> 1) + 1) return (left + right) / 2.067
寻找旋转排序数组中的最小值。
这里旋转一次的定义是把一个末尾元素放到头部。
问题是一开始有一个排序数组,现在被旋转了未知的次数,要找到最小值。
被旋转后的数组的“形状”大概是先升再掉到最低点,再升。
所以可以每次二分的时候和最后一个元素比较。
如果当前位置更大,说明最低点在右边。
如果当前位置更小,说明最低点在左边。
class Solution: def findMin(self, nums: List[int]) -> int: l = 0 r = len(nums)
while l < r: mid = (l + r) >> 1 if nums[mid] <= nums[-1]: r = mid else: l = mid + 1
return nums[l]66
搜索旋转排序数组。
数组和上一题一样,但这次不是找最小值而是找目标值。
思路是先找出最小值,分两段做简单二分。
class Solution: def findMin(self, nums: List[int]) -> int: l = 0 r = len(nums)
while l < r: mid = (l + r) >> 1 if nums[mid] <= nums[-1]: r = mid else: l = mid + 1
return l
def search(self, nums: List[int], target: int) -> int: min_idx = self.findMin(nums) min_v = nums[min_idx] if target <= nums[-1]: l = min_idx r = len(nums) while l < r: mid = (l + r) >> 1 if nums[mid] >= target: r = mid else: l = mid + 1 if l < len(nums) and nums[l] == target: return l else: l = 0 r = min_idx - 1 while l < r: mid = (l + r) >> 1 if nums[mid] >= target: r = mid else: l = mid + 1 if l < len(nums) and nums[l] == target: return l
return -165
在排序数组中查找元素的第一个和最后一个位置。
简单二分。
class Solution: def searchRange(self, nums: List[int], target: int) -> List[int]: l, r = 0, len(nums) while l < r: mid = (l + r) >> 1 if nums[mid] >= target: r = mid else: l = mid + 1 if l >= len(nums) or nums[l] != target: return [-1, -1] ans1 = l l, r = 0, len(nums) while l < r: mid = (l + r) >> 1 if nums[mid] > target: r = mid else: l = mid + 1 return [ans1, l - 1]64
搜索二维矩阵。
有一个排序的二维数组,问有没有目标值。
每次和右上角比对,排除一行或一列。
class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: i, j = 0, len(matrix[0]) - 1 while i < len(matrix) and j >= 0: if matrix[i][j] == target: return True if matrix[i][j] < target: i += 1 elif matrix[i][j] > target: j -= 1 return False63
搜索插入位置。
最最简单的二分。
class Solution: def searchInsert(self, nums: List[int], target: int) -> int: l, r = 0, len(nums) while l < r: mid = (l + r) >> 1 if nums[mid] >= target: r = mid else: l = mid + 1 return l62
N皇后。
经典搜索。
class Solution: def solveNQueens(self, n: int) -> List[List[str]]: board = [['.' for _ in range(n)] for _ in range(n)] ans = []
col = [False] * n dia1 = [False] * (2 * n - 1) dia2 = [False] * (2 * n - 1)
def dfs(u): if u == n: ans.append([''.join(row) for row in board]) return for i in range(n): if col[i] or dia1[i - u + n - 1] or dia2[i + u]: continue
board[u][i] = 'Q' col[i] = True dia1[i - u + n - 1] = True dia2[i + u] = True
dfs(u + 1)
board[u][i] = '.' col[i] = False dia1[i - u + n - 1] = False dia2[i + u] = False
dfs(0) return ans61
分割回文串。
经典搜索。
class Solution: def partition(self, s: str) -> List[List[str]]: ans = [] tmp = [] n = len(s)
def check(s) -> bool: for i in range(len(s) // 2): if s[i] != s[len(s) - 1 - i]: return False return True
def dfs(u): if u >= n: ans.append(tmp[:]) for length in range(1, n - u + 1): if check(s[u:u + length]): tmp.append(s[u:u + length]) dfs(u + length) tmp.pop()
dfs(0) return ans