LeetCode 73. 矩阵置零

73. 矩阵置零

提示

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

示例 1:

LeetCode 73. 矩阵置零_第1张图片

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

示例 2:

LeetCode 73. 矩阵置零_第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

进阶:

  • 一个直观的解决方案是使用  O(_m__n_) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(_m_ + _n_) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗?

题解

为了解决这个问题,我们可以使用一种不需要额外空间的方法。基本思想是使用矩阵的第一行和第一列来记录哪些行和列需要被置零。这样,我们就不需要分配额外的空间来存储这些信息。

算法步骤如下:

  1. 检查第一行和第一列是否需要置零:首先检查第一行和第一列是否原本就包含 0,因为后面的步骤会修改这两个区域。

  2. 使用第一行和第一列作为标记:遍历整个矩阵,对于矩阵中的每个元素,如果它是 0,则将其所在行的第一个元素和所在列的第一个元素设置为 0。

  3. 根据标记置零:再次遍历矩阵(除了第一行和第一列),根据第一行和第一列的标记来决定是否将当前元素置零。

  4. 根据第一步的结果置零第一行和第一列:如果第一步中发现第一行或第一列中有 0,则将整个第一行或第一列置零。

C++ 代码实现:

void setZeroes(vector<vector<int>>& matrix) {
    bool firstRowZero = false, firstColZero = false;
    int rows = matrix.size(), cols = matrix[0].size();

    // Check if first row or first column need to be set to zero
    for (int i = 0; i < rows; ++i) {
        if (matrix[i][0] == 0) {
            firstColZero = true;
            break;
        }
    }
    for (int j = 0; j < cols; ++j) {
        if (matrix[0][j] == 0) {
            firstRowZero = true;
            break;
        }
    }

    // Use first row and column as markers
    for (int i = 1; i < rows; ++i) {
        for (int j = 1; j < cols; ++j) {
            if (matrix[i][j] == 0) {
                matrix[i][0] = 0;
                matrix[0][j] = 0;
            }
        }
    }

    // Set elements to zero according to markers
    for (int i = 1; i < rows; ++i) {
        for (int j = 1; j < cols; ++j) {
            if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                matrix[i][j] = 0;
            }
        }
    }

    // Set first row and column to zero if needed
    if (firstColZero) {
        for (int i = 0; i < rows; ++i) {
            matrix[i][0] = 0;
        }
    }
    if (firstRowZero) {
        for (int j = 0; j < cols; ++j) {
            matrix[0][j] = 0;
        }
    }
}

复杂度分析:

  • 时间复杂度:O(m * n),其中 m 和 n 分别是矩阵的行数和列数。我们需要两次遍历整个矩阵。
  • 空间复杂度:O(1),不需要使用额外的空间,我们利用了矩阵的第一行和第一列来存储信息。

你可能感兴趣的:(leetcode,矩阵,算法)