每日leetcode-数组-73. 矩阵置零
分类:数组-二维数组变换
题目描述:
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
进阶:
一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个仅使用常量空间的解决方案吗?
解题思路:
两遍扫matrix
,第一遍用集合记录哪些行,哪些列有0
;第二遍置0 用 O(m+n)额外空间
class Solution: def setZeroes(self, matrix: List[List[int]]) -> None: """ Do not return anything, modify matrix in-place instead. """ m = len(matrix) n = len(matrix[0]) row = set() col = set() for i in range(m): for j in range(n): if matrix[i][j] == 0: row.add(i) col.add(j) for i in range(m): for j in range(n): if i in row or j in col: matrix[i][j] = 0 return matrix
空间复杂度 O(1) 的算法
空间复杂度为 O(1),也就是说只能用常量的空间,难度就突然加大了。
方法的整体思想是:类似于使用 set 保存每行列是否需要置零,但是使用了第 0 行和第 0 列来保存 matrix[1:M][1:N] 中是否出现了 0;那么 第 0 行和第 0 列的数据就不是输入的原始数据了,被「污染」。因此,为了知道第 0 行和第 0 列是否有 0,就必须提前统计,把污染前的数据放到 row0 和 col0 中。
这个方法可以分为四步走:
统计 matrix 第 0 行 和 第 0 列 是否有 0,保存到 row0, col0 中;
遍历 matrix[1:M][1:N] 看当前位置是否有 0,如果有 0,则把信息记录到 matrix 的第 0 行以及第 0 列中。
根据 matrix 中第 0 行以及第 0 列的 0,将 matrix[1:M][1:N] 对应的行或者列全部置 0;
根据 row0, col0 判断 第 0 行 和 第 0 列 是否需要全部置 0。
class Solution: def setZeroes(self, matrix: List[List[int]]) -> None: if not matrix or not matrix[0]: return M, N = len(matrix), len(matrix[0]) row0, col0 = False, False for i in range(M): if matrix[i][0] == 0: col0 = True for j in range(N): if matrix[0][j] == 0: row0 = True 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 row0: for j in range(N): matrix[0][j] = 0 if col0: for i in range(M): matrix[i][0] = 0