LeetCode-73-矩阵置零
in LeetCode with 0 comment

LeetCode-73-矩阵置零

in LeetCode with 0 comment

原题地址:矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 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]
]

进阶:

$O(MN)$空间复杂度算法

用一个数组记录矩阵中所有的0对应的行和列,然后将这些0对应的行和列全部清0即可,具体的实现方法如下:

/**
 * @param {number[][]} matrix
 * @return {void} Do not return anything, modify matrix in-place instead.
 */
const setZeroes1 = function(matrix) {
    if (matrix.length === 0) {
        return;
    }
    let [m, n] = [matrix.length, matrix[0].length];
    // 记录所有的0所在的行和列
    let array = [];
    for (let i = 0; i < m; i ++) {
        for (let j = 0; j < n; j ++) {
            if (matrix[i][j] === 0) {
                array.push([i, j]);
            }
        }
    }
    // 对于每个0,将它的行和列全部清0
    for (let item of array) {
        for (let i = 0; i < n; i ++) {
            matrix[item[0]][i] = 0;
        }
        for (let i = 0; i < m; i ++) {
            matrix[i][item[1]] = 0;
        }
    }
};

测试:

let start = new Date();
const test = setZeroes1;
let matrix = [
    [1,1,1],
    [1,0,1],
    [1,1,1]
];
test(matrix);
console.log(matrix); // [ [ 1, 0, 1 ], [ 0, 0, 0 ], [ 1, 0, 1 ] ]
matrix = [
    [0,1,2,0],
    [3,4,5,2],
    [1,3,1,5]
];
test(matrix);
console.log(matrix); // [ [ 0, 0, 0, 0 ], [ 0, 4, 5, 0 ], [ 0, 3, 1, 0 ] ]
console.log(new Date().getTime() - start.getTime()); // 8

时间复杂度: 记录0所在的位置时间复杂度为$O(MN)$,清空0所在的行和列时间复杂度为$O(MN(M+N))$,所以总的时间复杂度为$O(MN(M+N+1))$
空间复杂度: 空间复杂度为$O(MN)$

$O(M+N)$空间复杂度算法

用两个数组分别记录有0存在的行和列,然后再分别将这些行和列全部清0即可,具体的实现如下:

/**
 * @param {number[][]} matrix
 * @return {void} Do not return anything, modify matrix in-place instead.
 */
const setZeroes2 = function(matrix) {
    if (matrix.length === 0) {
        return;
    }
    let [m, n] = [matrix.length, matrix[0].length];
    // 分别记录有0存在的行和列
    let [arrayM, arrayN] = [[], []];
    for (let i = 0; i < m; i ++) {
        for (let j = 0; j < n; j ++) {
            if (matrix[i][j] === 0) {
                arrayM.push(i);
                break;
            }
        }
    }
    for (let i = 0; i < n; i ++) {
        for (let j = 0; j < m; j ++) {
            if (matrix[j][i] === 0) {
                arrayN.push(i);
                break;
            }
        }
    }
    // 有0存在的行列,对应行列全部清0
    for (let item of arrayM) {
        for (let i = 0; i < n; i ++) {
            matrix[item][i] = 0;
        }
    }
    for (let item of arrayN) {
        for (let i = 0; i < m; i ++) {
            matrix[i][item] = 0;
        }
    }
};

测试:

let start = new Date();
const test = setZeroes2;
let matrix = [
    [1,1,1],
    [1,0,1],
    [1,1,1]
];
test(matrix);
console.log(matrix); // [ [ 1, 0, 1 ], [ 0, 0, 0 ], [ 1, 0, 1 ] ]
matrix = [
    [0,1,2,0],
    [3,4,5,2],
    [1,3,1,5]
];
test(matrix);
console.log(matrix); // [ [ 0, 0, 0, 0 ], [ 0, 4, 5, 0 ], [ 0, 3, 1, 0 ] ]
console.log(new Date().getTime() - start.getTime()); // 8

时间复杂度: 记录有0存在行和列,时间复杂度为$O(2MN)$,清空这些行和列,时间复杂度为$O(2MN)$,所以总时间复杂度为$O(4MN)=O(MN)$
空间复杂度: 空间复杂度为$O(M+N)$