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 == matrix0.length

    1 <= m, n <= 200

    -231 <= matrixij <= 231 - 1

  • 进阶:

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

题解

  1. 核心要点
    • 标记0的位置:
      使用两个向量 row 和 col 来分别标记包含0的行和列。row 的长度为矩阵的行数 m,col 的长度为矩阵的列数 n。初始时,所有元素都设置为 false。
    • 遍历矩阵:
      第一个循环遍历矩阵的每个元素 matrixij
      如果发现元素值为0,则将对应的 rowi 和 colj 标记为 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的行和列。

遍历矩阵的每个元素:

当我们遇到 matrix11 = 0 时,我们将 row1 和 col1 标记为 true。

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

row: false, true, false

col: false, true, false

第二步:置零操作

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

遍历矩阵的每个元素:

对于 matrix10,由于 row1 为 true,我们将其置零。

对于 matrix11,它已经是零,保持不变。

对于 matrix12,由于 row1 为 true,我们将其置零。

对于 matrix01 和 matrix21,由于 col1 为 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;
}
相关推荐
CSharp精选营14 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
洛卡卡了15 小时前
我们在用 AI 写代码时,为什么建议要好好维护 AGENTS.md 呢?
面试·agent·claude
PBitW15 小时前
GPT训练我的第三天,明白了应该咋说满分回答!😕😕😕
前端·javascript·面试
自由路飞1 天前
RAG 混合检索深挖:BM25 和向量分数为什么不能直接相加?
面试
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
未秃头的程序猿1 天前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
To_OC1 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC1 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
阳光是sunny1 天前
Vue 项目怎么做用户行为全链路监控?轻量插件方案详解
前端·面试·架构
蝎子莱莱爱打怪1 天前
DSpark 讲透:DeepSeek 不换模型,硬把 V4 提速 85%,是怎么做到的?
人工智能·面试·程序员