javascript解力扣面试题 01.08. 零矩阵

本文介绍了如何高效地处理矩阵中零元素,通过三种解法探讨时间复杂度与空间复杂度的权衡:O(n^3)但低空间复杂度的深拷贝法,O(n^3)但空间复杂度为1的NaN替换法,以及O(n^2)空间复杂度O(n)的双向标记法。适合理解矩阵操作和优化算法的程序员参考。
摘要由CSDN通过智能技术生成

面试题 01.08. 零矩阵

题目描述

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

解答

var setZeroes = function(matrix) {
    // 解法1:时间复杂度O(n^3),时间复杂度O(n^2)
    // 深拷贝一个相同的matrix作为参照helper,然后检测helper中的0,改变原数组对应行列元素
    // 执行用时:80 ms, 在所有 JavaScript 提交中击败了97.11%的用户
    // 内存消耗:40.7 MB, 在所有 JavaScript 提交中击败了23.09%的用户
    let helper = JSON.parse(JSON.stringify(matrix));
    for (let i = 0; i < helper.length; ++i) {
        for (let j = 0; j < helper[0].length; ++j) {
            if (!helper[i][j]) {
                for (let k = 0; k < helper.length; ++k) matrix[k][j] = 0;
                for (let k = 0; k < helper[0].length; ++k) matrix[i][k] = 0;
            }
        }
    }
     
    // 解法2:时间复杂度O(n^3),空间复杂度O(1)
    // 两次遍历,第一遍先把应该改为0的改成特殊值NaN,第二遍把NaN改为0
    // 注意:isNaN(number)判断number是否为NaN
    // 执行用时:96 ms, 在所有 JavaScript 提交中击败了45.41%的用户
    // 内存消耗:41.2 MB, 在所有 JavaScript 提交中击败了18.11%的用户
    for (let i = 0; i < matrix.length; ++i) {
        for (let j = 0; j < matrix[0].length; ++j) {
            if (matrix[i][j] === 0) {
                for (let k = 0; k < matrix.length; ++k) if ( matrix[k][j] !== 0) matrix[k][j] = NaN;
                for (let k = 0; k < matrix[0].length; ++k) if ( matrix[i][k] !== 0) matrix[i][k] = NaN;
            }
        }
    }
    for (let i = 0; i < matrix.length; ++i) {
        for (let j = 0; j < matrix[0].length; ++j) {
            if (isNaN(matrix[i][j])) matrix[i][j] = 0;
        }
    }
    // 解法3:时间复杂度O(n^2),空间复杂度O(n)
    // 两个一维向量分别记录行或者列上是否有0,第二遍遍历时查找对应的记录向量是否有true
    // 执行用时:92 ms, 在所有 JavaScript 提交中击败了59.32%的用户
    // 内存消耗:39.5 MB, 在所有 JavaScript 提交中击败了96.59%的用户
    const m = matrix.length, n = matrix[0].length;
    const rowFlag = new Array(m).fill(false);
    const colFlag = new Array(n).fill(false);
    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            if (matrix[i][j] === 0) {
                rowFlag[i] = true;
                colFlag[j] = true;
            }
        }
    }
    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            if(rowFlag[i] || colFlag[j]) matrix[i][j] = 0;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值