返回

算法打卡| 今日挑战LeetCode第73题矩阵置零

后端

在二维矩阵中遇到 0,就让行和列归零:巧妙的算法

在计算机科学中,我们经常需要处理二维矩阵。有时,我们可能会遇到这样一个问题:如果矩阵中的某个元素为 0,我们需要将它所在的行和列的所有元素都置为 0。乍一看,这似乎是一个很复杂的任务,但其实有一个非常巧妙的算法可以解决它。

算法步骤

  1. 创建一个新的矩阵: 首先,我们需要创建一个与给定矩阵大小相同的新的矩阵。这个新矩阵将用于存储我们的结果。
  2. 查找 0 元素: 接下来,我们需要遍历给定矩阵,并找出所有为 0 的元素。
  3. 标记行和列: 当我们发现一个 0 元素时,我们将它所在的行和列的所有元素都标记为 0。我们可以使用额外的数组或哈希表来存储这些标记。
  4. 置为 0: 最后,我们将所有标记为 0 的元素实际置为 0。

代码示例

class Solution {
    public void setZeroes(int[][] matrix) {
        // 创建一个行标志数组和一个列标志数组
        boolean[] rowFlags = new boolean[matrix.length];
        boolean[] colFlags = new boolean[matrix[0].length];

        // 标记包含 0 的行和列
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    rowFlags[i] = true;
                    colFlags[j] = true;
                }
            }
        }

        // 将包含 0 的行和列置为 0
        for (int i = 0; i < matrix.length; i++) {
            if (rowFlags[i]) {
                for (int j = 0; j < matrix[0].length; j++) {
                    matrix[i][j] = 0;
                }
            }
        }

        for (int j = 0; j < matrix[0].length; j++) {
            if (colFlags[j]) {
                for (int i = 0; i < matrix.length; i++) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
}

算法分析

  • 时间复杂度: O(m*n),其中 m 和 n 分别是矩阵的行数和列数。
  • 空间复杂度: O(m+n),其中 m 和 n 分别是矩阵的行数和列数。

结论

这个算法利用了一个巧妙的策略,通过标记和置零来有效地处理二维矩阵中的 0 元素。它具有高效的时间和空间复杂度,使其成为解决此类问题的绝佳选择。

常见问题解答

  1. 如果矩阵中存在多个 0 元素,该算法还能正常工作吗?
    是的,该算法可以处理矩阵中任意数量的 0 元素。它将标记所有包含 0 的行和列,并相应地将它们置为 0。

  2. 这个算法可以用于稀疏矩阵吗?
    是的,该算法特别适用于稀疏矩阵,因为标记和置零的操作只需要 O(m+n) 的时间,而无需遍历整个矩阵。

  3. 该算法是否可以修改为仅修改包含 0 的行和列?
    是的,我们可以通过在算法中添加一个额外的步骤来实现这一点。我们可以先创建一个包含所有包含 0 的行和列索引的新矩阵,然后仅修改这些行和列。

  4. 这个算法是否可以用更少的空间来实现?
    是的,可以使用位掩码技术来将空间复杂度降低到 O(1)。我们可以使用两个 32 位整数来分别标记包含 0 的行和列。

  5. 该算法是否适用于非方形矩阵?
    是的,该算法可以应用于任意大小和形状的矩阵,而不仅仅是方形矩阵。