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;
}
相关推荐
蛋蛋的就会顺顺的4 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday4 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
开发小能手1235 小时前
答案daanC语言
数据结构·算法
小 黄 鸡5 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
Navigator_Z6 小时前
LeetCode //C - 1291. Sequential Digits
c语言·算法·leetcode
WL学习笔记7 小时前
C & C++ 内存管理
c++·c++内存管理
启观川8 小时前
数据结构与算法-第 3 章 常用算法-贪心算法
数据结构·笔记·python·算法·贪心算法
程序员清风9 小时前
堆与优先队列:从 Top K 到任务调度
java·数据结构·算法
宛 禾9 小时前
Qt 控件入门:QLabel 从拖拽到对象树,一篇讲透
c++·qt·学习
suhan9 小时前
【数据结构】四、串:串string、模式匹配BF\KMP、广义表
数据结构·后端·算法