LeetCode [中等]矩阵置零

73. 矩阵置零 - 力扣(LeetCode)

暴力解法

用两个标记数组分别记录每一行和每一列是否有零出现。

  • 遍历该数组一次,如果某个元素为 0,那么就将该元素所在的行和列所对应标记数组的位置置为 true。
  • 再次遍历该数组,用标记数组更新原数组即可。

时间复杂度:O(mn),其中 m 是矩阵的行数,n 是矩阵的列数。至多只需要遍历该矩阵两次。

空间复杂度:O(m+n),其中 m 是矩阵的行数,n 是矩阵的列数。需要分别记录每一行或每一列是否有零出现。

cs 复制代码
public class Solution {
    public void SetZeroes(int[][] matrix) {
        int m = matrix.Length, n = matrix[0].Length;
        bool[] row = new bool[m];
        bool[] col = new bool[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;
                }
            }
        }
    }
}

使用两个标记变量

使用两个额外的变量记录原矩阵的第一行第一列是否包含0。之后便可以修改matrix[0][j]和 matrix[i][0]的数据。

用原矩阵的 第一行 matrix[0][j] 和第一列 matrix[i][0],来代替原来的两个标记数组,从而减少使用的空间。

cs 复制代码
public class Solution {
    public void SetZeroes(int[][] matrix) {
        int m = matrix.Length, n = matrix[0].Length;
        bool flagCol0 = false, flagRow0 = false;
        //第一列
        for(int i = 0; i < m; i++)
        {
            if(matrix[i][0] == 0)
            {
                flagCol0 = true;
                break;
            }
        }
        //第一行
        for(int j = 0; j < n; j++)
        {
            if(matrix[0][j] == 0)
            {
                flagRow0 = true;
                break;
            }
        }
        //从第二行第二列开始遍历矩阵,将0结点的行列保存在第一行第一列中
        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;
            }
        }

        //从第二行第二列开始遍历矩阵,根据第一行第一列中的的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)。我们只需要常数空间存储若干变量。

相关推荐
551只玄猫1 天前
KNN算法基础 机器学习基础1 python人工智能
人工智能·python·算法·机器学习·机器学习算法·knn·knn算法
charliejohn1 天前
计算机考研 408 数据结构 哈夫曼
数据结构·考研·算法
POLITE31 天前
Leetcode 41.缺失的第一个正数 JavaScript (Day 7)
javascript·算法·leetcode
CodeAmaz1 天前
一致性哈希与Redis哈希槽详解
redis·算法·哈希算法
POLITE31 天前
Leetcode 42.接雨水 JavaScript (Day 3)
javascript·算法·leetcode
Tim_101 天前
【算法专题训练】36、前缀树路径和
算法
好易学·数据结构1 天前
可视化图解算法76:最大子数组和
数据结构·算法·leetcode·面试·动态规划·力扣·笔试
副露のmagic1 天前
更弱智的算法学习 day13
学习·算法