1. 项目概述
作为一名常年混迹LeetCode的Python开发者,我决定整理这份"热题100"中普通数组和矩阵类题目的Python3题解合集。不同于其他题解单纯贴代码,我会用最贴近工程实践的方式,拆解每道题的核心算法思想和Python实现技巧。
这个系列特别适合:
- 准备面试却对数组/矩阵题型发怵的求职者
- 能写出暴力解但不会优化的算法新手
- 想学习Pythonic写法的其他语言开发者
提示:所有代码均在Python 3.8+测试通过,包含时间复杂度分析和空间优化技巧
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心解题方法论
2.1 数组问题处理框架
数组类题目通常考察以下能力:
- 边界条件处理(空数组、单元素等)
- 双指针技巧(快慢指针、滑动窗口)
- 哈希表辅助查找
- 原地修改数组的技巧
以经典题「移动零」为例:
python复制def moveZeroes(nums):
slow = 0
for fast in range(len(nums)):
if nums[fast] != 0:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
关键点:
- 使用快慢双指针避免额外空间
- 交换操作保证非零元素的原始顺序
- 时间复杂度O(n),空间O(1)
2.2 矩阵问题四步法
矩阵类题目解题套路:
- 确定遍历方向(螺旋、对角线等)
- 处理边界收缩(旋转类题目)
- 利用辅助数据结构(集合记录访问位置)
- 数学规律应用(转置、镜像等)
比如「旋转图像」的Python实现:
python复制def rotate(matrix):
n = len(matrix)
# 对角线翻转
for i in range(n):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 水平翻转
for row in matrix:
row.reverse()
3. 高频题型深度解析
3.1 最长连续序列(#128)
暴力解陷阱:
直接排序后遍历看似简单,但时间复杂度是O(nlogn),不符合题目要求的O(n)
优化方案:
python复制def longestConsecutive(nums):
num_set = set(nums)
max_len = 0
for num in num_set:
if num - 1 not in num_set: # 确保是序列起点
current_num = num
current_len = 1
while current_num + 1 in num_set:
current_num += 1
current_len += 1
max_len = max(max_len, current_len)
return max_len
踩坑记录:直接用list会导致查找时间复杂度为O(n),必须转为set
3.2 矩阵置零(#73)
空间优化技巧:
- 常规解法需要O(m+n)空间记录清零行列
- 进阶解法用矩阵第一行列作为标记位:
python复制def setZeroes(matrix):
m, n = len(matrix), len(matrix[0])
first_row_has_zero = any(matrix[0][j] == 0 for j in range(n))
first_col_has_zero = any(matrix[i][0] == 0 for i in range(m))
# 使用第一行列记录清零位置
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
matrix[i][0] = 0
matrix[0][j] = 0
# 执行清零
for i in range(1, m):
for j in range(1, n):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
# 处理第一行列
if first_row_has_zero:
for j in range(n):
matrix[0][j] = 0
if first_col_has_zero:
for i in range(m):
matrix[i][0] = 0
4. Python特优解法集锦
4.1 利用生成器节省内存
在「杨辉三角」(#118)中:
python复制def generate(numRows):
def _next_row(prev):
return [1] + [prev[i]+prev[i+1] for i in range(len(prev)-1)] + [1]
result = []
prev = []
for _ in range(numRows):
prev = _next_row(prev)
result.append(prev)
return result
优化点:
- 使用闭包避免重复计算
- 列表推导式比循环更Pythonic
4.2 使用zip处理矩阵转置
「翻转字符串里的单词」(#151)的矩阵思维解法:
python复制def reverseWords(s):
return ' '.join(reversed(s.split()))
# 进阶:不使用split的实现
def reverseWords(s):
words = []
word = []
for ch in s:
if ch != ' ':
word.append(ch)
elif word:
words.append(''.join(word))
word = []
if word:
words.append(''.join(word))
return ' '.join(reversed(words))
5. 常见错误与调试技巧
5.1 数组越界问题
在「搜索二维矩阵II」(#240)中常见错误:
python复制# 错误示范
def searchMatrix(matrix, target):
i, j = 0, len(matrix[0])-1
while i < len(matrix) and j >= 0:
if matrix[i][j] == target:
return True
elif matrix[i][j] < target:
i += 1 # 可能越界
else:
j -= 1 # 可能越界
return False
修正方案:
python复制def searchMatrix(matrix, target):
if not matrix or not matrix[0]:
return False
rows, cols = len(matrix), len(matrix[0])
i, j = 0, cols - 1
while 0 <= i < rows and 0 <= j < cols:
if matrix[i][j] == target:
return True
elif matrix[i][j] < target:
i += 1
else:
j -= 1
return False
5.2 深浅拷贝问题
在「组合总和」(#39)等回溯问题中:
python复制# 错误示范
result = []
path = []
def backtrack(nums, target):
if target == 0:
result.append(path) # 错误!添加的是同一个list对象
return
for num in nums:
if num > target:
continue
path.append(num)
backtrack(nums, target - num)
path.pop()
正确做法:
python复制result = []
def backtrack(nums, target, path):
if target == 0:
result.append(list(path)) # 创建新列表
return
for num in nums:
if num > target:
continue
path.append(num)
backtrack(nums, target - num, path)
path.pop()
6. 性能优化实战
6.1 利用缓存装饰器
在「最长递增子序列」(#300)中:
python复制from functools import lru_cache
def lengthOfLIS(nums):
@lru_cache(maxsize=None)
def dp(i):
max_len = 1
for j in range(i):
if nums[j] < nums[i]:
max_len = max(max_len, dp(j) + 1)
return max_len
return max(dp(i) for i in range(len(nums))) if nums else 0
6.2 使用bisect模块
优化后的LIS解法:
python复制import bisect
def lengthOfLIS(nums):
tails = []
for num in nums:
idx = bisect.bisect_left(tails, num)
if idx == len(tails):
tails.append(num)
else:
tails[idx] = num
return len(tails)
复杂度从O(n²)降到O(nlogn)
7. 矩阵特殊操作技巧
7.1 螺旋遍历矩阵(#54)
python复制def spiralOrder(matrix):
if not matrix:
return []
m, n = len(matrix), len(matrix[0])
res = []
left, right, top, bottom = 0, n-1, 0, m-1
while left <= right and top <= bottom:
# 从左到右
res.extend(matrix[top][j] for j in range(left, right+1))
# 从上到下
res.extend(matrix[i][right] for i in range(top+1, bottom+1))
if left < right and top < bottom:
# 从右到左
res.extend(matrix[bottom][j] for j in range(right-1, left-1, -1))
# 从下到上
res.extend(matrix[i][left] for i in range(bottom-1, top, -1))
left += 1
right -= 1
top += 1
bottom -= 1
return res
7.2 对角线遍历(#498)
python复制def findDiagonalOrder(matrix):
if not matrix:
return []
m, n = len(matrix), len(matrix[0])
res = []
for s in range(m + n - 1):
# 确定对角线起点
if s % 2 == 0:
i = min(s, m-1)
j = s - i
while i >= 0 and j < n:
res.append(matrix[i][j])
i -= 1
j += 1
else:
j = min(s, n-1)
i = s - j
while j >= 0 and i < m:
res.append(matrix[i][j])
i += 1
j -= 1
return res
8. 高频考点总结
8.1 必掌握数组操作
| 操作类型 | 代表题目 | 核心技巧 |
|---|---|---|
| 双指针 | #11 盛水容器 | 左右指针向中间收敛 |
| 滑动窗口 | #3 无重复字符 | 哈希集合维护窗口 |
| 前缀和 | #560 和为K子数组 | 累计和与哈希表配合 |
| 区间合并 | #56 合并区间 | 排序后线性扫描 |
8.2 矩阵高频考点
| 题型 | 经典题目 | 解题要点 |
|---|---|---|
| 旋转操作 | #48 旋转图像 | 对角线翻转+水平翻转 |
| 搜索优化 | #240 搜索矩阵II | 从右上角开始的二叉搜索 |
| 动态规划 | #64 最小路径和 | 二维DP表优化空间 |
| 特殊遍历 | #54 螺旋矩阵 | 边界收缩法 |
9. 调试与测试技巧
9.1 自定义测试用例生成
对于矩阵问题,可以这样快速生成测试数据:
python复制import random
def generate_matrix(m, n, low=0, high=9):
return [[random.randint(low, high) for _ in range(n)] for _ in range(m)]
# 生成3x3的随机矩阵
test_matrix = generate_matrix(3, 3)
9.2 可视化调试
对于二维数组问题,添加打印函数:
python复制def print_matrix(matrix):
for row in matrix:
print(' '.join(f'{num:2}' for num in row))
print()
# 调试螺旋矩阵时使用
matrix = [[1,2,3],[4,5,6],[7,8,9]]
print_matrix(matrix)
10. 进阶挑战与扩展
10.1 自定义矩阵类
实现一个支持常见操作的矩阵类:
python复制class Matrix:
def __init__(self, data):
self.data = data
self.rows = len(data)
self.cols = len(data[0]) if self.rows > 0 else 0
def transpose(self):
return Matrix(list(zip(*self.data)))
def rotate_clockwise(self):
return Matrix([list(row)[::-1] for row in zip(*self.data)])
def __str__(self):
return '\n'.join(' '.join(map(str, row)) for row in self.data)
10.2 并行计算优化
对于大规模矩阵运算,可以使用multiprocessing:
python复制from multiprocessing import Pool
def matrix_multiply_parallel(a, b):
n = len(a)
with Pool() as pool:
result = pool.starmap(
lambda i, j: sum(a[i][k] * b[k][j] for k in range(n)),
[(i, j) for i in range(n) for j in range(n)]
)
return [result[i*n:(i+1)*n] for i in range(n)]
在实际刷题过程中,我发现数组和矩阵类题目最考验代码的严谨性。一个常见的建议是:先写出暴力解,再分析哪些步骤可以优化,最后考虑边界条件。记住LeetCode的测试用例往往比面试官给的更严格,能通过所有测试的代码才算是真正可靠的解法。
