力扣(LeetCode)100题:73.矩阵置零 54.螺旋矩阵
73.矩阵置零
class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""row={}column={}len_r=len(matrix)len_c=len(matrix[0])for i in range(len_r):for j in range(len_c):if matrix[i][j]==0:if i not in row:row[i]=[]if j not in column:column[j]=[]for i in range(len_r):for j in range(len_c):if i in row or j in column:matrix[i][j]=0
代码思路(两步走)
第一步:扫描并记录哪些行和列包含 0
- 遍历整个矩阵。
- 一旦发现
matrix[i][j] == 0,就记下:- 第
i行需要清零 → 存入row - 第
j列需要清零 → 存入column
- 第
- 这里用了字典(虽然值没用,但键的存在就表示“该行/列有 0”)。
✅ 本质:先收集所有要清零的行号和列号,避免在遍历时边改边扫导致误判。
第二步:根据记录,将对应行和列全部置 0
- 再次遍历整个矩阵。
- 对每个位置
(i, j):- 如果
i在row中(该行有 0),或者j在column中(该列有 0), - 就把
matrix[i][j]设为0。
- 如果
54.螺旋矩阵
from typing import Listclass Solution:def spiralOrder(self, matrix: List[List[int]]) -> List[int]:if not matrix or not matrix[0]: # 处理空矩阵(边界条件)return []ans = []top = 0 # 上边界(初始第一行)bottom = len(matrix) - 1 # 下边界(初始最后一行)left = 0 # 左边界(初始第一列)right = len(matrix[0]) - 1 # 右边界(初始最后一列)while top <= bottom and left <= right:# 1. 从左到右:遍历当前上边界的行for col in range(left, right + 1):ans.append(matrix[top][col])top += 1 # 上边界向下收缩(已遍历完当前行)if top > bottom:break# 2. 从上到下:遍历当前右边界的列for row in range(top, bottom + 1):ans.append(matrix[row][right])right -= 1 # 右边界向左收缩(已遍历完当前列)if left > right:break# 3. 从右到左:遍历当前下边界的行(注意:此时top <= bottom才需要遍历)for col in range(right, left - 1, -1):ans.append(matrix[bottom][col])bottom -= 1 # 下边界向上收缩(已遍历完当前行)if top > bottom:break# 4. 从下到上:遍历当前左边界的列(注意:此时left <= right才需要遍历)for row in range(bottom, top - 1, -1):ans.append(matrix[row][left])left += 1 # 左边界向右收缩(已遍历完当前列)if left > right:breakreturn ans
核心思路:按层模拟螺旋路径
将矩阵看作由外向内一圈圈的“层”,每一圈按 右 → 下 → 左 → 上 的顺序遍历,并在每一步后收缩对应的边界,直到所有元素被访问。
四个方向 + 边界收缩
用四个变量动态维护当前可遍历的范围:
top:当前最上行bottom:当前最下行left:当前最左列right:当前最右列
循环条件:top <= bottom and left <= right(还有未遍历的区域)
1. 从左到右(沿 top 行)
- 遍历列:
left → right - 完成后:
top += 1(上边界下移)
2. 从上到下(沿 right 列)
- 遍历行:
top → bottom - 完成后:
right -= 1(右边界左移)
3. 从右到左(沿 bottom 行)
- 遍历列:
right → left - 完成后:
bottom -= 1(下边界上移)
4. 从下到上(沿 left 列)
- 遍历行:
bottom → top - 完成后:
left += 1(左边界右移)
⚠️ 关键细节:每步后检查边界
每次收缩边界后,立即检查是否越界(如 top > bottom),若越界则提前 break,避免重复或无效遍历。
例如:当矩阵只有一行时,第一步(从左到右)后
top超过bottom,后续步骤应跳过。
