[JavaScript / leetcode] 面试题 01.08. 零矩阵

30 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情

每日刷题 2022.10.19

题目

  • 编写一种算法,若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]
]

提示

  • 1 <= nums.length <= 10^5
  • -231 <= nums[i] <= 231-1
  • -10^5 <= lower <= upper <= 10^5
  • 题目数据保证答案是一个 32 位 的整数

解题思路

  • 不删减数组的元素,就会导致下标比较难处理。
  • 并且需要注意:需要while循环判断当前是否已经被标记过,标记过的下标就不能再次被计算。
  • 创建一个标记数组vis,用于记录当前的小伙伴是否被淘汰。
    • 如果被淘汰了,就记录为1;否则记为0
  • 最终的结果,就是vis数组中为0的单元格

具体的分析

  • vis数组的功能,上述已经提到:arr数组的功能,就是通过数组的下标和vis数组形成映射,在最后找到vis数组中仅存的一个vis[idx] = 0时,答案就是arr[idx]
  • 具体步骤:
    • 遍历原矩阵,若当前元素为0,则将行索引和列索引添加到相应的集合中;
    • 遍历行,若当前行索引在集合中,将整行置零;
    • 遍历列,若当前列索引在集合中,将整列置零。

代码

/**
 * @param {number[][]} matrix
 * @return {void} Do not return anything, modify matrix in-place instead.
 */
var setZeroes = function(matrix) {
  let setC = new Set(), setR = new Set(), n = matrix.length, m = matrix[0].length;
  for(let i = 0; i < n; i++) {
    for(let j = 0; j < m; j++) {
      if(matrix[i][j] === 0) {
        setC.add(i);
        setR.add(j);
      }
    }
  }
  for(let i = 0; i < n; i++) {
    for(let j = 0; j < m; j++) {
      if(setC.has(i) || setR.has(j)) {
        matrix[i][j] = 0;
      }
    }
  }
  return matrix;
};