矩阵置零[中等]

优质博文:IT-BLOG-CN

一、题目

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

示例 1:

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]

输出:[[1,0,1],[0,0,0],[1,0,1]]

示例 2:

输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]

输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-231 <= matrix[i][j] <= 231 - 1

二、代码

【1】使用标记数组: 我们可以用两个标记数组分别记录每一行和每一列是否有零出现。具体地,我们首先遍历该数组一次,如果某个元素为0,那么就将该元素所在的行和列所对应标记数组的位置置为true。最后我们再次遍历该数组,用标记数组更新原数组即可。

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean[] row = new boolean[m];
        boolean[] col = new boolean[n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = col[j] = true;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (row[i] || col[j]) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
}

时间复杂度: O(mn),其中m是矩阵的行数,n是矩阵的列数。我们至多只需要遍历该矩阵两次。
空间复杂度: O(m+n),其中m是矩阵的行数,n是矩阵的列数。我们需要分别记录每一行或每一列是否有零出现。

【2】使用两个标记变量: 我们可以用矩阵的第一行和第一列代替方法一中的两个标记数组,以达到O(1)的额外空间。但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 000。因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含0。在实际代码中,我们首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列,然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean flagCol0 = false, flagRow0 = false;
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                flagCol0 = true;
            }
        }
        for (int j = 0; j < n; j++) {
            if (matrix[0][j] == 0) {
                flagRow0 = true;
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][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 (flagCol0) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
        if (flagRow0) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }
    }
}

时间复杂度: O(mn),其中m是矩阵的行数,n是矩阵的列数。我们至多只需要遍历该矩阵两次。
空间复杂度: O(1)。我们只需要常数空间存储若干变量。

使用一个标记变量: 我们可以对方法二进一步优化,只使用一个标记变量记录第一列是否原本存在0。这样,第一列的第一个元素即可以标记第一行是否出现0。但为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素。

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean flagCol0 = false;
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                flagCol0 = true;
            }
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        for (int i = m - 1; i >= 0; i--) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
            if (flagCol0) {
                matrix[i][0] = 0;
            }
        }
    }
}

时间复杂度: O(mn),其中m是矩阵的行数,n是矩阵的列数。我们至多只需要遍历该矩阵两次。
空间复杂度: O(1)。我们只需要常数空间存储若干变量。

相关推荐
QxQ么么4 小时前
移远通信(桂林)26校招-助理AI算法工程师-面试纪录
人工智能·python·算法·面试
better_liang4 小时前
每日Java面试场景题知识点之-分布式事务处理
java·微服务·面试·springcloud·分布式事务
爱学习的小可爱卢5 小时前
JavaEE进阶——SpringMVC响应处理详解
spring boot·postman·javaee
q***96586 小时前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
7***68436 小时前
Spring Boot 从 2.7.x 升级到 3.3注意事项
数据库·hive·spring boot
L***d6706 小时前
Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
java·数据库·spring boot
凌波粒6 小时前
Springboot基础教程(3)--自动装配原理/静态资源处理/欢迎页
java·spring boot·后端
likuolei6 小时前
XSL-FO 软件
java·开发语言·前端·数据库
凌波粒6 小时前
SpringBoot基础教程(2)--yaml/配置文件注入/数据校验/多环境配置
java·spring boot·后端·spring
S***26756 小时前
Spring Boot环境配置
java·spring boot·后端