leetcode 面试经典 150 题:矩阵置零

链接 矩阵置零
题序号 73
题型 二维数组
解题方法 标记数组法
难度 中等
熟练度 ✅✅✅✅

题目

给定一个 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

    -2^31^ <= matrix[i][j] <= 2^31^ - 1

  • 进阶:

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

题解

  1. 核心要点
    • 标记0的位置:
      使用两个向量 row 和 col 来分别标记包含0的行和列。row 的长度为矩阵的行数 m,col 的长度为矩阵的列数 n。初始时,所有元素都设置为 false。
    • 遍历矩阵:
      第一个循环遍历矩阵的每个元素 matrix[i][j]。
      如果发现元素值为0,则将对应的 row[i] 和 col[j] 标记为 true。
    • 置零操作:
      第二个循环再次遍历矩阵,根据 row 和 col 的标记,将对应的行和列置零。
  2. 时间复杂度:O(mn)
  3. 空间复杂度:O(m+n)
  4. c++ 实现算法:
cpp 复制代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> row(m), col(n);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (!matrix[i][j]) {
                    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;
                }
            }
        }
    }
};
  1. 演示:以示例1为例

假设我们有以下矩阵:

[

[1, 1, 1],

[1, 0, 1],

[1, 1, 1]

]

我们需要将所有包含0的行和列置零。

第一步:标记0的位置

我们使用两个向量 row 和 col 来标记包含0的行和列。

遍历矩阵的每个元素:

当我们遇到 matrix[1][1] = 0 时,我们将 row[1] 和 col[1] 标记为 true。

标记后的 row 和 col 向量如下:

row: [false, true, false]

col: [false, true, false]

第二步:置零操作

根据 row 和 col 的标记,我们将对应的行和列置零。

遍历矩阵的每个元素:

对于 matrix[1][0],由于 row[1] 为 true,我们将其置零。

对于 matrix[1][1],它已经是零,保持不变。

对于 matrix[1][2],由于 row[1] 为 true,我们将其置零。

对于 matrix[0][1] 和 matrix[2][1],由于 col[1] 为 true,我们将其置零。

最终得到的矩阵如下:

[

[1, 0, 1],

[0, 0, 0],

[1, 0, 1]

]

  1. c++ 完整demo:
cpp 复制代码
#include <vector>
#include <iostream>

using namespace std;

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> row(m), col(n);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (!matrix[i][j]) {
                    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;
                }
            }
        }
    }
};

// 用于打印矩阵的函数
void printMatrix(const vector<vector<int>>& matrix) {
    for (const auto& row : matrix) {
        for (int num : row) {
            cout << num << " ";
        }
        cout << endl;
    }
}

int main() {
    // 创建一个示例矩阵
    vector<vector<int>> matrix = {
        {1, 1, 1},
        {1, 0, 1},
        {1, 1, 1}
    };
    
    cout << "Original matrix:" << endl;
    printMatrix(matrix);
    
    Solution solution;
    solution.setZeroes(matrix);
    
    cout << "Matrix after setting zeros:" << endl;
    printMatrix(matrix);
    
    return 0;
}
相关推荐
喉咙痛的恐龙8 分钟前
C++之“string”类的模拟实现
开发语言·c++
阿巴~阿巴~11 分钟前
C/C++蓝桥杯算法真题打卡(Day3)
c语言·c++·算法·蓝桥杯
<但凡.28 分钟前
题海拾贝:P9241 [蓝桥杯 2023 省 B] 飞机降落
数据结构·算法·蓝桥杯
Spring小子33 分钟前
蓝桥杯[每日两题] 真题:好数 神奇闹钟 (java版)
java·数据结构·算法·蓝桥杯
记得早睡~1 小时前
leetcode654-最大二叉树
javascript·数据结构·算法·leetcode
圣保罗的大教堂1 小时前
leetcode 2070. 每一个查询的最大美丽值 中等
leetcode
Java中文社群1 小时前
面试官:你项目是如何保证高可用的?
java·后端·面试
狂炫一碗大米饭1 小时前
Event Loop事件循环机制,那是什么事件?又是怎么循环呢?
前端·javascript·面试
程序员小续1 小时前
React 组件库:跨版本兼容的解决方案!
前端·react.js·面试
写代码的橘子n1 小时前
unordered_set 的常用函数
数据结构·算法·哈希算法