73. 矩阵置零 - 力扣LeetCodeclass Solution: def setZeroes(self, matrix: List[List[int]]) - None: m, n len(matrix), len(matrix[0]) # 先单独记录第一行 / 第一列本身是否含 0它们即将被当作标记板会被污染 first_row_zero any(matrix[0][j] 0 for j in range(n)) first_col_zero any(matrix[i][0] 0 for i in range(m)) # 第一遍扫内部区域发现 0 就把标记打到第一行、第一列上 for i in range(1, m): for j in range(1, n): if matrix[i][j] 0: matrix[i][0] 0 # 标记第 i 行要清零 matrix[0][j] 0 # 标记第 j 列要清零 # 第二遍扫内部区域根据标记统一置零 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_zero: for j in range(n): matrix[0][j] 0 if first_col_zero: for i in range(m): matrix[i][0] 0易错点① 时间复杂度O(mn)空间复杂度O(1)② 本质是将第一行第一列 “借用于” 记录哪些行或列需要被清零因此处理顺序不能乱必须最后一步才对第一行 / 第一列清零先清就失去了标记③ 为什么不能在发现元素为 0 时就立刻清行清列新写入的 0 和矩阵原有的 0 无法分清会引发 “连锁清零”思路第一行、第一列当标记位先标记后置零54. 螺旋矩阵 - 力扣LeetCodeclass Solution: def spiralOrder(self, matrix: list[list[int]]) - list[int]: ans[] top,bottom0,len(matrix)-1 left,right0,len(matrix[0])-1 while topbottom and leftright: for j in range(left,right1): ans.append(matrix[top][j]) top1 for i in range(top,bottom1): ans.append(matrix[i][right]) right-1 if topbottom: for j in range(right, left-1, -1): ans.append(matrix[bottom][j]) bottom-1 if leftright: for i in range(bottom, top-1, -1): ans.append(matrix[i][left]) left1 return ans易错点① 时间复杂度O(mn)② 两个 “if判断” 是最高频翻车点它们必须存在用 1×3 和 3×1 的矩阵手动模拟一遍就能理解它们为什么必须存在可能会倒回去记录③ 倒序range(right, left - 1, -1)容易将终点写作left那样将漏掉最左一个元素48. 旋转图像 - 力扣LeetCodeclass Solution: def rotate(self, matrix: list[list[int]]) - None: Do not return anything, modify matrix in-place instead. m, n len(matrix), len(matrix[0]) for i in range(0,m): for j in range(i,n): matrix[i][j], matrix[j][i] matrix[j][i], matrix[i][j] for row in matrix: row.reverse() return matrix口决先沿主对角线转置再将每行左右翻转注意 j 必须从 i 开始否则等同于不翻转240. 搜索二维矩阵 II - 力扣LeetCodeclass Solution: def searchMatrix(self, matrix: List[List[int]], target: int) - bool: top, bottom 0, len(matrix)-1 left, right 0, len(matrix[0])-1 while topbottom and leftright: if matrix[top][right]target: top 1 elif matrix[top][right]target: right - 1 else: return True易错点① 时间复杂度O(mn)② 本质是利用了左下角或右上角元素的特殊性质进行剪枝此处以右上角为例分析它是本行最大、本列最小当前值比 target 大本列下方全都更大整列可以扔掉向左走当前值比 target 小本行左侧全都更小整行可以扔掉向下走每一步稳定扔掉一行或一列最多走 mn 步因此相对地左上角及右下角元素不具备上述性质因此不能将其作为起始点四道题四个独立套路共同点是利用矩阵自身的结构省掉额外空间上述四个解法空间复杂度均为 O(1)