力扣73.矩阵置零

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

 解法一:

class Solution {
public:
    // 这个函数用于将给定的矩阵中的所有零所在的行和列都设置为零
    void setZeroes(vector<vector<int>>& matrix) {
        // 获取矩阵的行数和列数
        int rows = matrix.size();
        int cols = matrix[0].size();
        
        // 创建两个向量作为行和列的标志,初始化为false
        vector<bool> row(rows, false);
        vector<bool> col(cols, false);
        
        // 遍历矩阵,如果找到零,则在相应的行和列标志中标记
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = true;  // 标记第i行包含零
                    col[j] = true;  // 标记第j列包含零
                }
            }
        }
        
        // 再次遍历矩阵,根据行和列标志将相应元素设置为零
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (row[i] || col[j]) {
                    matrix[i][j] = 0;  // 如果第i行或第j列被标记,则该元素设置为零
                }
            }
        }
    }
};

这个函数的思路是遍历矩阵两次,第一次标记每一行和每一列是否包含零,第二次根据这些标记将对应位置的元素置为零。

具体步骤如下:

  1. 首先获取矩阵的行数和列数,分别保存在变量rows和cols中。
  2. 创建两个向量row和col作为行和列的标志,初始化为false。这两个向量的长度分别为rows和cols。
  3. 第一次遍历矩阵,对于每一个元素matrix[i][j],如果它的值为0,则在相应的行标志row[i]和列标志col[j]中标记为true,表示第i行或第j列包含零。
  4. 第二次遍历矩阵,对于每一个元素matrix[i][j],如果第i行或第j列的标志row[i]或col[j]为true,则将该元素设置为零。
  5. 最终,矩阵中所有零所在的行和列都被设置为零。

这种方法的时间复杂度为O(m*n),其中m和n分别为矩阵的行数和列数。空间复杂度为O(m+n),需要额外的row和col向量来保存行和列的标志位。

 

解法二: 

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int rows=matrix.size(),colows=matrix[0].size();
        bool falg_col0=false,falg_row0=false;
        for(int i=0;i<rows;i++){
            if(matrix[i][0]==0)
            falg_col0=true;
        }
        for(int i=0;i<colows;i++){
            if(matrix[0][i]==0)
            falg_row0=true;
        }
        for(int i=1;i<rows;i++){
            for(int j=1;j<colows;j++){
                if(!matrix[i][j]){
                    matrix[i][0]=matrix[0][j]=0;
                }
            }
        }
        for(int i=1;i<rows;i++){
            for(int j=1;j<colows;j++){
                if(matrix[i][0]==0||matrix[0][j]==0)
                matrix[i][j]=0;
            }
        }
        if(falg_col0){
            for(int i=0;i<rows;i++){
                matrix[i][0]=0;
            }
        }
        if(falg_row0){
            for(int i=0;i<colows;i++){
                matrix[0][i]=0;
            }
        }
    }
};

这段代码使用了另一种优化的方法来解决问题。基本思路是利用矩阵的第一行和第一列作为标志位,用来记录每一行和每一列是否需要被置为零。具体步骤如下:

  1. 首先获取矩阵的行数和列数,分别保存在变量rows和colows中。
  2. 创建两个布尔变量falg_col0和falg_row0,用来标记第一列和第一行是否需要被置为零,初始值都为false。
  3. 遍历第一列,如果发现某个元素matrix[i][0]为零,则将falg_col0设置为true,表示第一列需要被置为零。
  4. 遍历第一行,如果发现某个元素matrix[0][i]为零,则将falg_row0设置为true,表示第一行需要被置为零。
  5. 从第二行和第二列开始,遍历整个矩阵。对于每个元素matrix[i][j],如果为零,则将对应的第一行元素matrix[i][0]和第一列元素matrix[0][j]设置为零,作为标志位。
  6. 再次遍历整个矩阵,对于每个元素matrix[i][j],如果对应的第一行元素matrix[i][0]或第一列元素matrix[0][j]为零,则将该元素设置为零。
  7. 最后,根据falg_col0和falg_row0的值,如果需要将第一列或第一行置为零,则遍历对应的行或列,将所有元素设置为零。

这种方法的时间复杂度为O(m*n),其中m和n分别为矩阵的行数和列数。只使用了两个额外的布尔变量,因此空间复杂度为O(1)。这是一种原地修改矩阵的优化方法,不需要额外的空间来保存标志位。

解法三:解法二优化版

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int rows = matrix.size(), cols = matrix[0].size();
        bool flag_col0 = false;
        for (int i = 0; i < rows; i++) {
            if (!matrix[i][0])
                flag_col0 = true;
            for (int j = 1; j < cols; j++) {
                if (!matrix[i][j]) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        for (int i = rows - 1; i >= 0; i--) {
            for (int j = 1; j < cols; j++) {
                if (!matrix[i][0] || !matrix[0][j])
                    matrix[i][j] = 0;
            }
            if (flag_col0) {
                matrix[i][0] = 0;
            }
        }
    }
};

 

这段代码使用了类似于前面的方法,但是稍微进行了一些优化。基本思路是:

  1. 首先获取矩阵的行数和列数,分别保存在变量rows和cols中。
  2. 创建一个布尔变量flag_col0,用来标记第一列是否需要被置为零,初始值为false。
  3. 遍历矩阵的每一行,从第一列开始。如果发现某个元素matrix[i][0]为零,则将flag_col0设置为true,表示第一列需要被置为零。
  4. 对于每个元素matrix[i][j],如果为零,则将对应的第一行元素matrix[i][0]和第一列元素matrix[0][j]设置为零,作为标志位。
  5. 再次遍历矩阵的每一行,从最后一列开始向前遍历。对于每个元素matrix[i][j],如果对应的第一行元素matrix[i][0]或第一列元素matrix[0][j]为零,则将该元素设置为零。
  6. 如果flag_col0为true,说明第一列需要被置为零,此时再遍历矩阵的每一行,将第一列元素都设置为零。

这种方法的时间复杂度为O(m*n),其中m和n分别为矩阵的行数和列数。空间复杂度为O(1),只使用了一个布尔变量来保存标志位。这种方法也是一种原地修改矩阵的优化方法,不需要额外的空间来保存标志位,并且减少了不必要的遍历。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值