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 stack

68#

寻找两个正序数组的中位数。

类似快速选择每次丢一半的思想。

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.0

67#

寻找旋转排序数组中的最小值。

这里旋转一次的定义是把一个末尾元素放到头部。

问题是一开始有一个排序数组,现在被旋转了未知的次数,要找到最小值。

被旋转后的数组的“形状”大概是先升再掉到最低点,再升。

所以可以每次二分的时候和最后一个元素比较。

如果当前位置更大,说明最低点在右边。

如果当前位置更小,说明最低点在左边。

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 -1

65#

在排序数组中查找元素的第一个和最后一个位置。

简单二分。

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 False

63#

搜索插入位置。

最最简单的二分。

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 l

62#

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 ans

61#

分割回文串。

经典搜索。

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