一、题目描述------矩阵置零
给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法 。
示例 1:

lua
输入: matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出: [[1,0,1],[0,0,0],[1,0,1]]
示例 2:

lua
输入: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
提示:
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-231 <= matrix[i][j] <= 231 - 1
二、题解(没错,这次的题解是完全自己写出来的,而且击败100.00%)
js
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var setZeroes = function(matrix) {
const ansSetI=new Set();
const ansSetJ=new Set();
for(let i=0;i<matrix.length;i++){
for(let j=0;j<matrix[i].length;j++){
if(matrix[i][j]===0){
ansSetI.add(i);
ansSetJ.add(j);
}
}
}
for(let i=0;i<matrix.length;i++){
for(let j=0;j<matrix[i].length;j++){
if( ansSetI.has(i)||ansSetJ.has(j)){
matrix[i][j]=0;
}
}
}
};
核心思想
利用两个集合(Set)分别记录需要置零的行索引和列索引。 第一遍扫描矩阵,记录下所有需要置零的行和列。 第二遍扫描矩阵,根据之前记录的行和列,将对应的元素置零。
详细步骤
-
初始化集合:
- 创建两个
Set
对象ansSetI
和ansSetJ
,分别用于存放需要置零的行索引和列索引。
- 创建两个
-
扫描矩阵,记录零元素位置:
-
使用嵌套循环遍历整个矩阵
matrix
。 -
对于矩阵中的每个元素
matrix[i][j]
:- 如果
matrix[i][j] === 0
,则将行索引i
添加到ansSetI
,将列索引j
添加到ansSetJ
。
- 如果
-
-
根据记录置零:
-
再次使用嵌套循环遍历整个矩阵
matrix
。 -
对于矩阵中的每个元素
matrix[i][j]
:- 如果
ansSetI.has(i)
(当前行需要置零)或者ansSetJ.has(j)
(当前列需要置零),则将matrix[i][j]
设置为0
。
- 如果
-
注意事项
- 空间复杂度: 由于使用了两个 Set 来存储行和列的索引,因此空间复杂度是 O(m + n),其中 m 和 n 分别是矩阵的行数和列数。 这题有O(1) space的解法,参见下面"优化方向"
- 原地修改: 题目要求 "Do not return anything, modify matrix in-place instead." 你的代码完全满足这个要求,直接修改了
matrix
,而没有返回任何东西。 - 集合的优点: 使用 Set 的好处是可以自动去重。即使某一行或某一列有多个 0,也只会记录一次,避免重复操作。
- 可读性: 代码的可读性很高,变量命名清晰,逻辑也很直观。
- 时间复杂度: 代码的时间复杂度是 O(m * n),其中 m 和 n 分别是矩阵的行数和列数。 因为需要遍历矩阵两次。
三、结语
再见!