算法学习记录(七十一)

213 阅读2分钟

73. 矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

image.png

解: 一、假设不考虑空间的问题,创建两个哈希表,遍历整个二维数组,如果遇到matrix[i][j]===0就在表中标记第i行第j列应该变成0。然后遍历表中数据,将matrix对应位置变成0即可。

二、但是本题要求原地转变。那么,可以将第0行,第0列看做之前解法中的哈希表。我们遍历matrix时,从第1行第1列开始,如果matrix[i][j]===0,那么将它对应第0行的第j列和第0列的第i行标记为0。当matrix遍历完成之后,通过第0行和第0列的数据中0的状况就可以知道哪些行列要被标记为0。但是仍有一个问题,那就是如果第0行或者第0列原本就有0,那么以上方法无法将第0行和第0列转为0,所以要先准备两个变量,记录第0行第0列是否有0。如果有的话,在最后一步时,将对应数据转为0。

const setZeroes = function(matrix) {
    // 第0行是否有0
    let firstRowFlag = false
    // 第0列是否有0
    let firstColFlag = false
    for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[0].length; j++) {
            // 判断第0行第0列是否有0
            if (i === 0 && j === 0) {
                firstColFlag = firstRowFlag = matrix[i][j] === 0
            } else 
            if (i === 0) {
                firstRowFlag = firstRowFlag ? firstRowFlag : matrix[i][j] === 0
            } else
            if (j === 0) {
                firstColFlag = firstColFlag ? firstColFlag : matrix[i][j] === 0
            } else
            if (matrix[i][j] === 0) {
                // 将i,j在第0行第0列中对应位置标记为0
                matrix[0][j] = 0
                matrix[i][0] = 0
            }
        }
    }
    // 根据第0列的数据将matrix中对应行标记为0
    for (let i = 1; i < matrix.length; i++) {
        if (matrix[i][0] === 0) {
            for (let j = 0; j < matrix[0].length; j++) {
                matrix[i][j] = 0
            }
        }
    }
    // 根据第0行的数据将matrix中对应列标记为0
    for (let i = 1; i < matrix[0].length; i++) {
        if (matrix[0][i] === 0) {
            for (let j = 0; j < matrix.length; j++) {
                matrix[j][i] = 0
            }
        }
    }
    // 最后根据第0行第0列是否有0,将第0行第0列也进行转换
    if (firstRowFlag) {
        for (let i = 0; i < matrix[0].length; i++) {
            matrix[0][i] = 0
        }
    }
    if (firstColFlag) {
        for (let i = 0; i < matrix.length; i++) {
            matrix[i][0] = 0
        }
    }
    return matrix
};