Skip to content

矩阵置零

理解题目:

题目要求对于给定的矩阵,如果矩阵中某个元素为 0,则将该元素所在的行和列都置为 0。

代码实现:

public class SetMatrixZeroes {
    // 矩阵置零
    public void setZeroes(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;

        // 使用两个标记变量来标记第一行和第一列是否需要置零
        boolean firstRowZero = false;
        boolean firstColZero = false;

        // 检查第一行和第一列是否需要置零
        for (int i = 0; i < m; i++) {
            // 遍历第一列,如果存在为 0的 元素,就说明第一列需要置0
            if (matrix[i][0] == 0) {
                firstColZero = true;
                break;
            }
        }
        for (int j = 0; j < n; j++) {
            // 遍历第一行,如果存在为 0的 元素,就说明第一行需要置0
            if (matrix[0][j] == 0) {
                firstRowZero = true;
                break;
            }
        }

        // 使用第一行和第一列作为标记数组,标记其余行列是否需要置零
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }

        // 根据标记数组的值,将相应的行列置零
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }

        // 最后根据标记变量,确定第一行和第一列是否需要置零
        if (firstRowZero) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }
        if (firstColZero) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
    }
}

步骤解释:

  1. 遍历矩阵,检查第一行和第一列是否需要置零,并用两个布尔变量 firstRowZerofirstColZero 记录下来。

  2. 使用第一行和第一列作为标记数组,遍历矩阵其余部分,将出现 0 的行和列的对应标记数组置为 0。

  3. 根据标记数组的值,将相应的行列置零。

  4. 最后根据 firstRowZerofirstColZero 变量,确定第一行和第一列是否需要置零。

时间复杂度: 遍历矩阵两次,时间复杂度为 O(mn)

空间复杂度: 只使用了常数级别的额外空间,空间复杂度为 O(1)