LeetCode探索(136):面试题 01.08. 零矩阵

226 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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)。

参考