持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题目
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
示例 1:
输入: [ [1,1,1], [1,0,1], [1,1,1] ] 输出: [ [1,0,1], [0,0,0], [1,0,1] ]
示例 2:
输入: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] 输出: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ]
思考
本题难度中等。
首先是读懂题意。题目中给出了二维数组 matrix,是一个 M × N 的矩阵。我们需要编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
这道题说难也不难,说简单也不简单。说简单,是因为我们可以遍历二维数组 matrix 的每个元素,如果其数值为0,则遍历其所在的行与列的所有元素并将其清零。但是,这种方法有点繁琐,因为会重复对某个元素赋值为0,效率很低。这也就是难的地方了。
我们可以借助标记数组来解题。也就是,定义数组rows和数组cols表示需要清零的行数和列数。遍历二维数组 matrix 的每个元素,如果其数值为0,则将其所在的行数和列数在数组rows和cols中标记为true。接着,再遍历一次数组,如果元素对应的rows和cols中的元素有一个为true,则将元素清零即可。
考虑到我们需要遍历该矩阵两次,因此时间复杂度是O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。
解答
方法一:借助标记数组
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var setZeroes = function(matrix) {
const m = matrix.length, n = matrix[0].length
const rows = new Array(m).fill(false)
const cols = new Array(n).fill(false)
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
if(matrix[i][j] === 0) {
rows[i] = cols[j] = true
}
}
}
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
if(rows[i] || cols[j]) {
matrix[i][j] = 0
}
}
}
}
复杂度分析:
- 时间复杂度:O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。我们需要遍历该矩阵两次。
- 空间复杂度:O(m+n)。