当前位置: 首页 > news >正文

面试经典150题[037]:矩阵置零(LeetCode 73)

矩阵置零(LeetCode 73)

题目链接:矩阵置零(LeetCode 73)
难度:中等

1. 题目描述

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法(不能用额外空间)。

要求:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -2^31 <= matrix[i][j] <= 2^31 - 1

示例:
在这里插入图片描述

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

在这里插入图片描述

输入: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]]

2. 问题分析

2.1 规律

想象矩阵像一张表格,如果某个格子是 0,就要把整行和整列的格子都变成 0。这像“零传染”一样,但不能用额外表格记录(因为要原地)。

简单说:先找所有 0 的位置,然后把那些行和列清零,但不能乱改数据,以免搞丢信息。

2.2 标记法思路

如果在某处遇到了0,最终都会传染到第一行和第一列,所以我们索性可以直接用矩阵的“边框”(第一行和第一列)来标记该行或列是否会被置零。

同时也要考虑到,边框里原本可能就有0,会把边框全部传染,所以我们应该先检查一下边框,如果真的有0则单独记录下来,最后把边框置零。

  1. 检查边框:先看第一行有没有 0(记在 row0 = True),第一列有没有 0(记在 col0 = True)。这样知道边框最后要不要清零。
  2. 找边框内部的0,并在边框上标记:从矩阵内(不碰边框)扫一遍。如果看到 0,就在边框上做标记:把这个0对应的行边框和列边框都标记为0,表示最终整行和整列都需要置0!
  3. 根据边框的0标记清零:从右下角开始扫(避免改了记号影响别人)。如果某行的边框标记是 0,就清整行;如果某列的边框标记是 0,就清整列。
  4. 最后清边框:根据步骤1的 row0col0,清第一行和第一列。

为什么从右下扫?因为记号在左上,改右下不会影响记号。

这样,只用两个小标志(row0 和 col0),空间 O(1)!

3. 代码实现

Python

class Solution:def setZeroes(self, matrix):if not matrix or not matrix[0]:returnm, n = len(matrix), len(matrix[0])row0 = any(matrix[0][j] == 0 for j in range(n))  # 第一行有0吗?col0 = any(matrix[i][0] == 0 for i in range(m))  # 第一列有0吗?# 步骤2:内里找0并标记边框for i in range(1, m):for j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = 0  # 标记行matrix[0][j] = 0  # 标记列# 步骤3:从右下扫,根据标记清零for i in range(m-1, 0, -1):  # 从下往上扫行if matrix[i][0] == 0:  # 这行要清for j in range(n-1, -1, -1):  # 清整行,从右到左matrix[i][j] = 0for j in range(n-1, 0, -1):  # 从右往左扫列if matrix[0][j] == 0:  # 这列要清for i in range(m-1, -1, -1):  # 清整列,从下到上matrix[i][j] = 0# 步骤4:清边框if row0:for j in range(n):matrix[0][j] = 0if col0:for i in range(m):matrix[i][0] = 0

C++

class Solution {
public:void setZeroes(vector<vector<int>>& matrix) {if (matrix.empty() || matrix[0].empty()) return;int m = matrix.size();int n = matrix[0].size();bool row0 = false;  // 第一行有0吗?bool col0 = false;  // 第一列有0吗?// 步骤1:检查边框for (int j = 0; j < n; ++j) {if (matrix[0][j] == 0) { row0 = true; break; }}for (int i = 0; i < m; ++i) {if (matrix[i][0] == 0) { col0 = true; break; }}// 步骤2:内里找0并标记for (int i = 1; i < m; ++i) {for (int j = 1; j < n; ++j) {if (matrix[i][j] == 0) {matrix[i][0] = 0;  // 标记行matrix[0][j] = 0;  // 标记列}}}// 步骤3:从右下扫清零for (int i = m - 1; i >= 1; --i) {if (matrix[i][0] == 0) {for (int j = n - 1; j >= 0; --j) {matrix[i][j] = 0;}}}for (int j = n - 1; j >= 1; --j) {if (matrix[0][j] == 0) {for (int i = m - 1; i >= 0; --i) {matrix[i][j] = 0;}}}// 步骤4:清边框if (row0) {fill(matrix[0].begin(), matrix[0].end(), 0);}if (col0) {for (int i = 0; i < m; ++i) {matrix[i][0] = 0;}}}
};

4. 复杂度分析

  • 时间复杂度:O(mn),扫几遍矩阵,但总共就这么多格子
  • 空间复杂度:O(1),只用两个 bool 变量

5. 总结

  • 原地清零 → 用边框当“便签”记位置,超聪明!
  • 记住顺序:检查 → 标记 → 清内 → 清边。一步错,全乱
    • 如果矩阵很大,时间够用;小矩阵直接试试看效果

6、复习

面试经典150题[007]:买卖股票的最佳时机(LeetCode 121)
面试经典150题[022]:Z 字形变换(LeetCode 6)

http://www.dtcms.com/a/392694.html

相关文章:

  • mysql 简单操作
  • Maven:Java项目的自动化构建工具
  • 嵌入式硬件工程师每日提问
  • 2025年AI写小说工具测评:AI写作软件大比拼
  • UL 2808 2020北美能源监测设备安全标准介绍
  • 刷题日记0920
  • 论文复现中的TODO
  • 什么是双向SSL/TLS(mTLS)?深入理解双向认证的守护神
  • app封装是什么意思
  • 什么是机房IP?有什么缺点
  • 【读书笔记】《谣言》
  • golang基础语法(一)变量
  • 私有化gitlab版本升级步骤(以版本12.9.0为例)
  • 基于java+springboot的超市仓库管理系统
  • Ubuntu 下练习编译 `.deb` 包的完整指南(适用于批量部署)
  • ICCV | 2025 | SkySense V2:面向多模态遥感的统一基础模型
  • 基于C# winform实现PP-HumanSeg人像分割替换背景色更换背景色
  • 对ai产品,设计测试case
  • ns-3 中一个最核心、最基本的概念——分组
  • C++八股 —— 编译过程
  • CMake笔记:cmake -G “NMake Makefiles“ 后,如何生成debug与release?
  • 解决 pip 安装报错:Could not find a suitable TLS CA certificate bundle
  • Python快速入门专业版(三十七):Python元组:不可变序列的特点与应用场景(对比列表)
  • 【UnoCSS快速上手】:安装、配置与优化,以及遇到的问题
  • 探索 Event 框架 5:实现Spring Boot集成
  • ARM(15) - LCD(2)显示字母数字+touch
  • 五、炫饭馆项目实战
  • 01.容器生态系统
  • CSS Grid 布局示例 - grid-template-areas
  • 基于脚手架微服务的视频点播系统-客户端业务逻辑处理部分(一)