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

Leetcode刷题记录29——矩阵置零

题源:https://leetcode.cn/problems/set-matrix-zeroes/description/?envType=study-plan-v2&envId=top-100-liked

题目描述:
在这里插入图片描述

思路一:

💡 解题思路

本题中我们采用如下策略:

  • 第一次遍历整个矩阵,记录所有值为 0 的元素的 行号列号
  • 使用两个集合 x_sety_set 分别保存需要置零的行索引和列索引。
  • 第二次分别对这些行和列进行置零操作。
    虽然这种方法没有做到最优的空间复杂度(O(1)),但它逻辑清晰、易于理解,是非常实用的一种实现方式。

✅ 具体实现步骤
第一步:获取矩阵尺寸

m = len(matrix)      # 行数
n = len(matrix[0])   # 列数

首先我们通过 len() 获取矩阵的行数和列数,便于后续遍历。

第二步:记录所有需要置零的行和列

x_set = set()  # 存储需要置零的行
y_set = set()  # 存储需要置零的列for i in range(m):for j in range(n):if matrix[i][j] == 0:x_set.add(i)y_set.add(j)

这里我们使用了两个集合来记录出现 0 的行和列,这样可以避免重复处理。

⚠️ 注意:使用集合是为了自动去重,避免多次添加相同的行或列。

第三步:将对应的行全部置为 0

for i in x_set:for j in range(n):matrix[i][j] = 0

对每一个需要置零的行 i,我们从第 0 列到第 n-1 列依次设置为 0。

第四步:将对应的列全部置为 0

for j in y_set:for i in range(m):matrix[i][j] = 0

同理,对每一个需要置零的列 j,我们从第 0 行到第 m-1 行依次设置为 0。

⏱️ 时间与空间复杂度分析
时间复杂度:O(m * n),每个元素最多被访问两次
空间复杂度:O(m + n),使用了两个集合存储行和列

✅ 优点:逻辑清晰、实现简单
❌ 缺点:未达到 O(1) 空间复杂度(进阶可优化)

代码如下:

class Solution(object):def setZeroes(self, matrix):""":type matrix: List[List[int]]:rtype: None Do not return anything, modify matrix in-place instead."""zero_index = []m = len(matrix)      # 行数n = len(matrix[0])   # 列数x_set= set()y_set = set()for i in range(m):for j in range(n):if matrix[i][j] == 0:x_set.add(i)y_set.add(j)# 将对应的行置零for i in x_set:for j in range(n):matrix[i][j] = 0# 将对应的列置零for j in y_set:for i in range(m):matrix[i][j] = 0

执行时间如下:
在这里插入图片描述

思路二:

核心思想:
利用矩阵的第一行和第一列来标记对应的列和行是否需要置零,这样就不需要额外的空间了。

但需要注意的是,第一行和第一列本身也可能被置零,所以我们需要用两个布尔变量来单独记录它们的状态。

✅ 具体实现步骤

第一步:初始化标记变量

first_row_has_zero = False  # 是否第一行需要置零
first_col_has_zero = False  # 是否第一列需要置零

这两个变量用于最后判断是否要将第一行或第一列整体置零。

第二步:检查第一列中是否有 0

for i in range(m):if matrix[i][0] == 0:first_col_has_zero = Truebreak

只要第一列中有一个 0,说明整列都要置零。

第三步:检查第一行中是否有 0

for j in range(n):if matrix[0][j] == 0:first_row_has_zero = Truebreak

同理,只要第一行中有 0,就说明整行要置零。

第四步:使用第一行和第一列作为标记数组
从第二行、第二列开始遍历整个矩阵:

for i in range(1, m):for j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = 0matrix[0][j] = 0

如果当前元素是 0,就把该行首和列首置零,表示这一行/列后续都需要置零。

第五步:根据标记置零中间部分

for i in range(1, m):if matrix[i][0] == 0:for j in range(1, n):matrix[i][j] = 0for j in range(1, n):if matrix[0][j] == 0:for i in range(1, m):matrix[i][j] = 0
  • 对于每一行,如果它的第一个元素是 0,则整行置零;
  • 对于每一列,如果它的第一个元素是 0,则整列置零。

第六步:处理第一行和第一列

if first_row_has_zero:for j in range(n):matrix[0][j] = 0if first_col_has_zero:for i in range(m):matrix[i][0] = 0

最后再根据最开始保存的两个布尔值来决定是否把第一行和第一列也置零。

⏱️ 时间与空间复杂度分析
时间复杂度:O(m * n),每个元素最多被访问两次
空间复杂度:O(1) ,只使用了常数级额外空间

代码如下:

class Solution(object):def setZeroes(self, matrix):""":type matrix: List[List[int]]:rtype: None Do not return anything, modify matrix in-place instead."""m = len(matrix)      # 行数n = len(matrix[0])   # 列数first_row_has_zero = False  # 是否第一行需要置零first_col_has_zero = False  # 是否第一列需要置零# 检查第一列是否有 0for i in range(m):if matrix[i][0] == 0:first_col_has_zero = Truebreak# 检查第一行是否有 0for j in range(n):if matrix[0][j] == 0:first_row_has_zero = Truebreak# 使用第一行和第一列作为标记数组for i in range(1, m):for j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = 0matrix[0][j] = 0# 根据标记置零中间部分for i in range(1, m):if matrix[i][0] == 0:for j in range(1, n):matrix[i][j] = 0for j in range(1, n):if matrix[0][j] == 0:for i in range(1, m):matrix[i][j] = 0# 处理第一行if first_row_has_zero:for j in range(n):matrix[0][j] = 0# 处理第一列if first_col_has_zero:for i in range(m):matrix[i][0] = 0

执行时间如下:
在这里插入图片描述

http://www.xdnf.cn/news/3649.html

相关文章:

  • 【JavaScript】性能优化:打造高效前端应用
  • 数据赋能(212)——质量管理——统一性原则
  • ROS2学习笔记|实现订阅消息并朗读的详细步骤
  • Easy云盘总结篇-登录注册
  • C# 编程核心:控制流与方法调用详解
  • 力扣每日一题 ​838. 推多米诺​
  • PyCharm中全局搜索无效
  • 软件测试名词科普:驱动模块、桩模块
  • springAop代理责任链模式源码解析
  • Socket-TCP
  • 【信息系统项目管理师】【2017年-2024年】计算画图题汇总——案例分析
  • [更新完毕]2025东三省B题深圳杯B题数学建模挑战赛数模思路代码文章教学:LED显示屏颜色转换设计与校正
  • ES6入门---第二单元 模块三:对象新增、
  • 深入理解 HttpExchange_Java 中构建 HTTP 服务的基础组件
  • 0基础 | STM32 | TB6612电机驱动使用
  • 2025年- H22-Lc130-206. 反转链表(链表)---java版
  • FreeRtos实战从入门到精通--任务创建和删除(动态方法)--事了拂衣去,深藏功与名
  • scikit-learn在监督学习算法的应用
  • linux下,ollama会把模型文件保存在哪里?
  • 神经网络基础-从零开始搭建一个神经网络
  • 【掌握 DDL】:SQL 中的数据库与表管理
  • 安卓基础(悬浮窗分级菜单和弹窗)
  • 【现代深度学习技术】现代循环神经网络04:双向循环神经网络
  • 游戏引擎学习第256天:XBox 控制器卡顿和修复 GL Blit 伽玛问题
  • java学习之数据结构:三、八大排序
  • 生成器模式(Builder Pattern)
  • 【Hive入门】Hive与Spark SQL深度集成:通过Spark ThriftServer高效查询Hive表
  • 【Unity】XLua访问C#文件
  • 第十四篇:系统分析师第三遍——15章
  • LeetCode —— 145. 二叉树的后序遍历