LeetCode ---- 73、矩阵置零

题目链接

思路:

直观的思路:遍历矩阵,记录下每一个0元素所在的行与列,然后再次遍历矩阵,若此时遍历到的位置的行或列中出现过0元素,则需要将此位置置为0。这是两次遍历,不可以合并为一次遍历。

空间复杂度为:O(m + n)

使用两个HashSet,分别存储当前位置的数为0时的行号与列号

    public void setZeroes(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return;
        }
        // 存放元素为0的行号
        HashSet<Integer> rows = new HashSet<>();
        // 存放元素为0的列号
        HashSet<Integer> cols = new HashSet<>();
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {  // 当前位置为0,则记录行号与列号
                    rows.add(i);
                    cols.add(j);
                }
            }
        }
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                // 当前位置所在行或列含有0元素,则需要将此位置置为0
                if (rows.contains(i) || cols.contains(j)) {
                    matrix[i][j] = 0;
                }
            }
        }
    }

原地解决此问题

即空间复杂度为O(1),思路如下:

利用原矩阵的第一行与第一列记录元素0所在的行与列

若当前位置的元素为0,则将它所在行的第一个元素与所在列的第一个元素都置为0,代表此行此列出现过0元素,需要将此行此列所有元素都置为0

由于第一行与第一列都用于记录此行此列是否存在元素0,对第一行与第一列元素有所破坏,所以需要对第一行与第一列的元素进行单独标记,单独处理
使用两个布尔类型的变量来记录第一行与第一列中是否出现过0元素。使用row0 来标记第一行中是否出现了0元素,使用col0来标记第一列中是否出现了0元素

代码参考自:https://leetcode-cn.com/problems/set-matrix-zeroes/comments/17518

    public void setZeroes(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return;
        }
        // 由于第一行与第一列都用于记录此行此列是否存在元素0,对第一行与第一列元素有所破坏
        // 所以需要对第一行与第一列的元素进行单独标记
        // 使用row0 来标记第一行中是否出现了0元素,使用col0来标记第一列中是否出现了0元素
        boolean row0 = false, col0 = false;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                // 当前位置元素为0
                if (matrix[i][j] == 0) {
                    // 当前位置为第一行
                    if (i == 0) {
                        row0 = true;
                    }
                    // 当前位置为第一列
                    if (j == 0) {
                        col0 = true;
                    }
                    // 此行此列的一个元素均置为0
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        // 从1,1位置开始遍历
        // 这是因为第一行与第一列是用来记录此行此列是否有元素0,需要进行处理
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                // 若当前位置所在行或所在列第一个元素为0,则说明这一行或这一列都需要置为0
                // 先将当前位置元素置为0
                if (matrix[0][j] == 0 || matrix[i][0] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        // 若第一行中本身含有0元素,则将第一行中所有元素置为0
        if (row0) {
            for (int j = 0; j < matrix[0].length; j++) {
                matrix[0][j] = 0;
            }
        }
        // 若第一列中本身含有0元素,则将第一列中所有元素置为0
        if (col0) {
            for (int i = 0; i < matrix.length; i++) {
                matrix[i][0] = 0;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/sinat_34679453/article/details/106891529
今日推荐