项目地址:Python_test_3
前言
今天集中攻克了三道矩阵类高频题,分别是:
其中迷宫寻路最考验细节,下面逐一总结。
一、螺旋矩阵(按层模拟)
核心思路
用四个变量 top, bottom, left, right 表示当前层的边界,每次按顺时针方向遍历四条边,然后收缩边界。
标准模板
def spiral_order(matrix):
if not matrix or not matrix[0]:
return []
m, n = len(matrix), len(matrix[0])
top, bottom, left, right = 0, m-1, 0, n-1
res = []
while top <= bottom and left <= right:
# 上边:从左到右
for j in range(left, right+1):
res.append(matrix[top][j])
top += 1
# 右边:从上到下
for i in range(top, bottom+1):
res.append(matrix[i][right])
right -= 1
# 下边:从右到左(需要检查 top <= bottom)
if top <= bottom:
for j in range(right, left-1, -1):
res.append(matrix[bottom][j])
bottom -= 1
# 左边:从下到上(需要检查 left <= right)
if left <= right:
for i in range(bottom, top-1, -1):
res.append(matrix[i][left])
left += 1
return res
易错点
- 单行或单列:遍历下边和左边前必须加 if 判断,否则会重复遍历。
- 边界更新顺序:每遍历完一边立即更新边界,保证下一次遍历的范围正确。
二、矩阵旋转(原地旋转)
核心思路
两步法:先上下翻转,再沿主对角线对称交换。
标准模板(n×n 方阵)
def rotate(matrix):
n = len(matrix)
# 1. 上下翻转
for i in range(n // 2):
matrix[i], matrix[n-1-i] = matrix[n-1-i], matrix[i]
# 2. 主对角线对称交换(只遍历上三角)
for i in range(n):
for j in range(i+1, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
易错点
- 对角线交换范围:必须是 j > i(上三角),不能遍历下三角,否则会重复交换导致还原。
- 上下翻转的循环次数:n // 2,奇数时中间一行不动。
- 原地操作:不需要额外矩阵,但需要临时变量(Python 元组交换自动处理)。
变体
- 逆时针旋转:先左右翻转,再主对角线对称;或先上下翻转,再副对角线对称。
三、迷宫寻路(DFS + parent 字典)
题目描述
给定 m×n 网格,0 可通行,1 障碍,从 (0,0) 到 (m-1,n-1),只能向右或向下,返回任意一条路径。
迭代 DFS 标准模板
def find_path(grid):
if not grid or not grid[0]:
return []
m, n = len(grid), len(grid[0])
# 起点或终点是障碍,直接返回
if grid[0][0] == 1 or grid[m-1][n-1] == 1:
return []
stack = [(0, 0)]
parent = {(0, 0): None} # 记录每个格子的前驱
found = False
while stack:
x, y = stack.pop()
if x == m-1 and y == n-1:
found = True
break
# 只向右和向下
for dx, dy in [(0, 1), (1, 0)]:
nx, ny = x + dx, y + dy
# 注意:检查新格子是否可通行,不是当前格子
if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 0 and (nx, ny) not in parent:
parent[(nx, ny)] = (x, y)
stack.append((nx, ny))
if not found:
return []
# 回溯路径
path = []
cur = (m-1, n-1)
while cur is not None:
path.append(cur)
cur = parent[cur]
path.reverse()
return path
⚠️ 细节陷阱(最容易摸错的地方)
陷阱1:起点/终点的障碍检查
# ❌ 错误:用 and
if grid[0][0] == 1 and grid[m-1][n-1] == 1:
return []
# ✅ 正确:用 or,只要有一个是障碍就返回
if grid[0][0] == 1 or grid[m-1][n-1] == 1:
return []
原因:起点或终点任一为障碍,都不可能到达,必须提前返回。
陷阱2:邻居合法性检查中的 grid 判断
# ❌ 错误:检查当前格子
if … and grid[x][y] == 0 and …
# ✅ 正确:检查新格子
if … and grid[nx][ny] == 0 and …
原因:当前格子 (x,y) 既然在栈中,说明它一定是可通行的(已通过前面的检查)。我们需要判断的是下一步要去的格子是否可通行。
陷阱3:parent 字典的初始化
# 正确写法
parent = {(0, 0): None}
原因:起点没有前驱,设为 None。回溯时作为终止条件。如果漏掉初始化,回溯到起点时会报 KeyError。
陷阱4:not in parent 的作用
if … and (nx, ny) not in parent:
作用:防止重复访问同一个格子。因为只能向右向下,理论上不会走回头路,但为了避免环形路径或重复入栈,加上这个判断更安全。同时,它也起到了 visited 的作用。
陷阱5:路径回溯的方向
# 从终点开始
cur = (m-1, n-1)
while cur is not None:
path.append(cur)
cur = parent[cur] # 跳到前一个格子
path.reverse() # 反转得到正确顺序
注意:parent 记录的是“从哪来”,所以回溯时是从终点倒着走到起点,最后必须反转。
陷阱6:栈的弹出顺序影响路径
- 使用 stack.pop()(后进先出)是 DFS,找到的路径不一定最短。
- 如果要求最短路径,应使用 BFS(队列 collections.deque)。
四、总结
|
螺旋矩阵 |
四边界变量 + 方向循环 |
单行/单列时的边界判断 |
|
矩阵旋转 |
上下翻转 + 对角线交换 |
对角线遍历范围(上三角) |
|
迷宫寻路 |
迭代 DFS + parent 字典 |
起点/终点检查、新格子判断、parent 初始化、回溯反转 |
矩阵类题型的关键在于边界条件的全覆盖和细节的严谨性。建议每道题至少手写三遍,直到闭眼能写出无 bug 的代码。
五、练习建议
祝你考试顺利,拿下 200 分!🚀
网硕互联帮助中心







评论前必须登录!
注册