1. 项目概述
最近在整理LeetCode热题100的Python3题解时,发现很多同学对普通数组和矩阵类题目存在理解障碍。作为刷过300+题的过来人,我决定把这两类高频题型的解题套路系统梳理出来,用最直白的语言配合可运行的代码,帮助大家快速掌握核心解法。
数组和矩阵题在面试中出现频率极高,约占LeetCode题库的30%。这类题目看似简单,但想要写出高效解法需要掌握一些特定的技巧和思维方式。下面我会从基础操作、常见题型到进阶优化,一步步拆解其中的门道。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数组核心操作与解题框架
2.1 数组基础操作四件套
处理数组题必须熟练掌握这四个基本操作:
- 遍历:for循环和while循环的选择
- 查找:线性查找与二分查找的应用场景
- 排序:内置sort()与自定义排序的妙用
- 双指针:快慢指针和左右指针的经典套路
以经典的"移动零"问题为例(LeetCode 283),最优解法就是双指针:
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
关键点:slow指针永远指向第一个0的位置,fast指针探索非零元素
2.2 前缀和与差分数组
遇到区间求和问题,前缀和技巧能大幅优化时间复杂度。比如"区域和检索 - 数组不可变"(LeetCode 303):
python复制class NumArray:
def __init__(self, nums):
self.prefix = [0] * (len(nums) + 1)
for i in range(len(nums)):
self.prefix[i+1] = self.prefix[i] + nums[i]
def sumRange(self, left, right):
return self.prefix[right+1] - self.prefix[left]
差分数组则是处理区间更新的利器,如"航班预订统计"(LeetCode 1109):
python复制def corpFlightBookings(bookings, n):
diff = [0] * (n + 2)
for first, last, seats in bookings:
diff[first] += seats
diff[last+1] -= seats
res = []
curr = 0
for i in range(1, n+1):
curr += diff[i]
res.append(curr)
return res
3. 矩阵问题解题方法论
3.1 矩阵遍历技巧
矩阵题最基础的是四种遍历方式:
- 螺旋遍历(LeetCode 54)
- 对角线遍历(LeetCode 498)
- 旋转遍历(LeetCode 48)
- 层序遍历(LeetCode 102)
以"旋转图像"为例,掌握原地旋转的数学规律:
python复制def rotate(matrix):
n = len(matrix)
# 先转置
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 再镜像
for row in matrix:
row.reverse()
3.2 岛屿类问题模板
岛屿问题(如LeetCode 200)有固定解题框架:
python复制def numIslands(grid):
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
count += 1
self.dfs(grid, i, j)
return count
def dfs(grid, i, j):
if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j]!='1':
return
grid[i][j] = '0'
dfs(grid, i+1, j)
dfs(grid, i-1, j)
dfs(grid, i, j+1)
dfs(grid, i, j-1)
注意:访问过的格子要立即标记,避免重复计算
4. 高频题型深度解析
4.1 最长连续序列(LeetCode 128)
这道题的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
关键点:只有当num是序列起点时才进行计算
4.2 搜索二维矩阵II(LeetCode 240)
利用矩阵排序特性进行高效搜索:
python复制def searchMatrix(matrix, target):
if not matrix:
return False
row, col = 0, len(matrix[0]) - 1
while row < len(matrix) and col >= 0:
if matrix[row][col] == target:
return True
elif matrix[row][col] < target:
row += 1
else:
col -= 1
return False
这种解法时间复杂度是O(m+n),比二分查找更优
5. 常见错误与调试技巧
5.1 数组越界问题
新手常犯的错误包括:
- 忘记检查空数组
- 循环边界条件错误
- 多维数组行列数搞混
调试建议:
- 打印循环变量的中间值
- 使用assert检查数组索引
- 对特殊用例进行测试(空数组、单元素数组等)
5.2 矩阵旋转的坑点
旋转矩阵时容易出现的错误:
- 混淆顺时针和逆时针旋转
- 没有考虑奇数阶矩阵的中心点
- 原地修改导致数据覆盖
实用调试方法:
- 先写出数学变换公式
- 用3x3矩阵手动模拟过程
- 分步骤打印旋转结果
6. 性能优化进阶技巧
6.1 空间换时间的典型场景
以下情况适合使用额外空间:
- 需要频繁查询统计信息
- 涉及大量重复计算
- 需要保存中间状态
比如"除自身以外数组的乘积"(LeetCode 238):
python复制def productExceptSelf(nums):
n = len(nums)
res = [1] * n
# 从左到右累积
left = 1
for i in range(n):
res[i] *= left
left *= nums[i]
# 从右到左累积
right = 1
for i in range(n-1, -1, -1):
res[i] *= right
right *= nums[i]
return res
6.2 位运算优化
某些数组问题可以用位运算大幅提速,如"只出现一次的数字"(LeetCode 136):
python复制def singleNumber(nums):
res = 0
for num in nums:
res ^= num
return res
异或运算的三个重要性质:
- a ^ 0 = a
- a ^ a = 0
- 满足交换律和结合律
7. 实战刷题建议
- 按题型分类练习,先数组后矩阵
- 每道题至少尝试两种解法
- 整理错题本,记录典型错误
- 定期复习高频题解模板
- 参加周赛锻炼实战能力
推荐练习顺序:
- 简单:26、27、66、118
- 中等:15、16、18、31
- 困难:41、128、287
最后分享一个实用技巧:遇到不会的题目时,先手动模拟小规模用例,往往能发现规律。比如在解决"旋转图像"时,我用2x2和3x3矩阵手动旋转,很快就理解了坐标变换规律。
