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

解法:

class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""if not matrix or not matrix[0]:returnm,n=len(matrix),len(matrix[0])# 1. 检查第一行/第一列是否原本就有0first_row_has_zero = any(matrix[0][j]==0 for j in range(n))first_col_has_zero = any(matrix[i][0]==0 for i in range(m))# 2. 用第一行和第一列作为“标记数组”# 也就是把要置为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# 3. 根据标记,把中间部分(非第一行/列)置零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# 4. 最后再处理第一行和第一列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 

使用5x5的矩阵来完整演示这个算法的每一步执行过程如下:


📌 示例矩阵:

原始矩阵:
[[ 1,  2,  3,  4,  5],[ 6,  7,  0,  8,  9],[10, 11, 12, 13, 14],[15,  0, 16, 17, 18],[19, 20, 21, 22, 23]
]

目标:如果某个元素是 0,就把它所在的整行和整列都设为 0。

我们使用 O(1) 空间优化算法(用第一行/列做标记)。


✅ 步骤 1:判断第一行和第一列是否原本有 0

first_row_has_zero = any(matrix[0][j] == 0 for j in range(5))False
first_col_has_zero = any(matrix[i][0] == 0 for i in range(5))False

第一行:[1,2,3,4,5] → 没有 0
第一列:[1,6,10,15,19] → 没有 0

✅ 所以最后我们不会主动清零第一行和第一列,除非标记需要。


✅ 步骤 2:用第一行和第一列作为“标记位”

我们从 (1,1) 开始扫描(跳过第一行和第一列),发现 0 就在 matrix[i][0]matrix[0][j] 打标记。

for i in range(1, 5):for j in range(1, 5):if matrix[i][j] == 0:matrix[i][0] = 0      # 标记第 i 行要清零matrix[0][j] = 0      # 标记第 j 列要清零

我们找到两个 0:

  1. matrix[1][2] == 0 → 第1行第2列是0

    • matrix[1][0] = 0 → 标记第1行要清零
    • matrix[0][2] = 0 → 标记第2列要清零
  2. matrix[3][1] == 0 → 第3行第1列是0

    • matrix[3][0] = 0 → 标记第3行要清零
    • matrix[0][1] = 0 → 标记第1列要清零

👉 打完标记后,矩阵变成:

[[ 1,  0,  0,  4,  5],   ← matrix[0][1]=0(第1列要清零),matrix[0][2]=0(第2列要清零)[ 0,  7,  0,  8,  9],   ← matrix[1][0]=0(第1行要清零)[10, 11, 12, 13, 14],[ 0,  0, 16, 17, 18],   ← matrix[3][0]=0(第3行要清零)[19, 20, 21, 22, 23]
]

🔔 注意:我们故意修改了第一行和第一列,把它们当作“标记墙”。


✅ 步骤 3:根据标记清零“中间部分”(非第一行/列)

① 清零被标记的行(从第1行开始)

for i in range(1, 5):if matrix[i][0] == 0:   # 第 i 行被标记了for j in range(1, 5):  # 把 j ≥ 1 的列清零matrix[i][j] = 0
  • i=1: matrix[1][0]==0 → 清零 matrix[1][1]matrix[1][4]
  • i=3: matrix[3][0]==0 → 清零 matrix[3][1]matrix[3][4]

当前矩阵:

[[ 1,  0,  0,  4,  5],[ 0,  0,  0,  0,  0],   ← 第1行清零(除了 matrix[1][0] 已是0)[10, 11, 12, 13, 14],[ 0,  0,  0,  0,  0],   ← 第3行清零[19, 20, 21, 22, 23]
]

② 清零被标记的列(从第1列开始)

for j in range(1, 5):if matrix[0][j] == 0:   # 第 j 列被标记了for i in range(1, 5):  # 把 i ≥ 1 的行清零matrix[i][j] = 0
  • j=1: matrix[0][1]==0 → 清零第1列(i=1 到 4)
  • j=2: matrix[0][2]==0 → 清零第2列(i=1 到 4)

注意:matrix[1][1], [1][2], [3][1], [3][2] 已是 0,但其他也要清:

  • 第1列:matrix[2][1], matrix[4][1] → 设为 0
  • 第2列:matrix[2][2], matrix[4][2] → 设为 0

当前矩阵:

[[ 1,  0,  0,  4,  5],[ 0,  0,  0,  0,  0],[10,  0,  0, 13, 14],   ← matrix[2][1] 和 [2][2] 被清零[ 0,  0,  0,  0,  0],[19,  0,  0, 22, 23]    ← matrix[4][1] 和 [4][2] 被清零
]

✅ 步骤 4:最后处理第一行和第一列

if first_row_has_zero:False → 不清零第一行for j in range(5): matrix[0][j] = 0if first_col_has_zero:False → 不清零第一列for i in range(5): matrix[i][0] = 0

所以第一行和第一列保持原样。


✅ 最终结果:

[[ 1,  0,  0,  4,  5],[ 0,  0,  0,  0,  0],[10,  0,  0, 13, 14],[ 0,  0,  0,  0,  0],[19,  0,  0, 22, 23]
]

✅ 验证是否正确?

原始 0 的位置:

  • (1,2) → 第1行、第2列 → 应清零 → ✅
  • (3,1) → 第3行、第1列 → 应清零 → ✅

结果:

  • 第1行全0 → ✅
  • 第3行全0 → ✅
  • 第1列:matrix[i][1] 全为0(i≥1)→ ✅
  • 第2列:matrix[i][2] 全为0(i≥1)→ ✅
  • 第一行和第一列未被误清 → ✅

✅ 总结:算法全过程

步骤操作目的
1检查第一行/列是否有 0保存原始信息
2扫描内部,用 matrix[i][0]matrix[0][j] 打标记空间复用,O(1)
3根据 matrix[i][0]==0 清零行读标记,清零中间行
4根据 matrix[0][j]==0 清零列读标记,清零中间列
5最后根据 first_row/col_has_zero 清零第一行/列保证完整性

💡 关键点回顾

  • matrix[i][0] == 0 确实是被前面改过的,但这是设计好的标记机制
  • 我们不是在“错误地读修改后的值”,而是在“正确地读标记”
  • 这就是 O(1) 空间解法的精髓用矩阵自己当哈希表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95182.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95182.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/95182.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣22】括号生成

数字n代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且有效的括号组合。 源代码&#xff1a; class Solution { public:int n;vector<string> ans;string path;vector<string> generateParenthesis(int n) {this->n n;d…

ELK分布式日志采集系统

* 系统架构&#xff1a;filebeat 采集各服务器日志&#xff1b;Logstash-docker 过滤整理日志&#xff1b; Elasticsearch-docker 存储和索引数据&#xff1b; Kibana-docker 提供可视化展示和操作。* FileBeat简介&#xff1a;Filebeat是本地文件的日志数据采集器。* Kafka简介…

Python生产环境部署指南:专业级应用启动方案

在生产环境中部署Python应用需要考虑稳定性、性能和安全性。本文将详细介绍多种专业部署方案,助你构建可靠的生产环境。 一、核心部署架构 标准Python生产环境包含三个核心组件: 应用服务器:运行Python代码(Gunicorn/uWSGI/Uvicorn) 进程管理器:保障服务持续运行(Supe…

C语言:结构体、共用体与枚举详解

在 C 语言编程中&#xff0c;结构体&#xff08;struct&#xff09;、共用体&#xff08;union&#xff09;与枚举&#xff08;enum&#xff09;是三种非常重要的用户自定义数据类型。它们能帮助我们更好地组织、管理和表达复杂的数据结构。本文将结合实例&#xff0c;深入介绍…

Linux Web服务器与WordPress部署笔记

web服务器 nginx 配置基本认证 用户名和密码使用plain text发送&#xff0c;所以最好配置SSL/TLS。 # 安装工具[rootserver ~ 09:21:43]# yum -y install httpd-tools[rootserver ~ 09:28:30]# vim /etc/nginx/conf.d/ssl.confserver {​location /auth-basic/ {auth_basic …

贪心----3. 跳跃游戏 II

45. 跳跃游戏 II - 力扣&#xff08;LeetCode&#xff09; /** 维护变量: max_reachable,遍历过的元素的最远可达位置 end,当前区间终点(随max_reachable变化) 遍历过程: 遍历时迭代遍历过的元素最远可达位置,利用end记录当前区间终点(随max_reachable变化) 当移动至end即当前…

RabbitMQ面试精讲 Day 13:HAProxy与负载均衡配置

【RabbitMQ面试精讲 Day 13】HAProxy与负载均衡配置 开篇 欢迎来到"RabbitMQ面试精讲"系列的第13天&#xff01;今天我们将聚焦RabbitMQ集群架构中的关键组件——HAProxy及其负载均衡配置。在大型分布式系统中&#xff0c;如何实现RabbitMQ集群的高可用和负载均衡是…

C# 中常用集合以及使用场景

1. 数组 (Array)‌‌特点‌&#xff1a;固定大小、内存连续、访问速度快‌使用场景‌&#xff1a;需要高性能的固定大小集合数值计算&#xff08;如矩阵运算&#xff09;存储已知长度的数据&#xff08;如配置文件参数&#xff09;‌2. List<T>‌‌特点‌&#xff1a;动态…

量化实战学习 Day 2:双均线策略实现与回测分析

一、前言在完成第一天的环境搭建和基础认知后&#xff0c;今天将进入真正的策略开发环节。本文将记录我从数据处理到第一个量化策略实现的全过程&#xff0c;包含完整的代码示例和深度思考。二、复习与环境检查1.1 环境复查首先确认了Day 1搭建的环境运行正常&#xff1a; cond…

ubuntu 安装内核模块驱动 DKMS 介绍

DKMS&#xff08;Dynamic Kernel Module Support&#xff0c;动态内核模块支持&#xff09;是一个用于管理 Linux 内核模块的工具&#xff0c;主要作用是在系统内核更新时&#xff0c;自动重新编译和安装依赖于特定内核版本的驱动程序&#xff08;内核模块&#xff09;&#xf…

adb使用指南

adb使用指南一、介绍二、连接一、有线连接方式二、无线连接方式**Android 10及以下版本****Android 11及以上版本**三、指令1、设备连接管理2、应用调试3、文件传输4、系统控制6、日志分析7、其他速查表总结python脚本实例&#xff1a;提示&#xff1a;以下是本篇文章正文内容&…

C语言实战:二级指针与文件操作的完美邂逅——动态管理文件数据

资料合集下载链接: ​https://pan.quark.cn/s/472bbdfcd014​ 在上一篇文章中,我们探讨了二级指针作为函数“输出特性”的强大功能。今天,我们将更进一步,通过一个完整的实战项目,将二级指针与文件I/O操作结合起来,学习如何动态、高效地读取和管理文件内容。 这个项目…

低代码开发实战案例,如何通过表单配置实现数据输入、数据存储和数据展示?

JVS低代码轻应用快速开发采用所见即所得的配置思路&#xff0c;表单是低代码中最基础的业务配置引擎之一&#xff0c;快速的通过表单配置实现数据输入、数据存储&#xff0c;数据展示。那么在轻应用下直接点开菜单打开的表单&#xff0c;录入数据提交到数据模型&#xff0c;后续…

数字孪生系统让汽车工厂虚实联动预测维护少停机

在汽车制造行业&#xff0c;设备突发停机往往会引发连锁反应&#xff0c;导致生产中断、成本飙升。传统运维模式依赖人工巡检与事后维修&#xff0c;难以应对复杂生产场景下的设备管理需求。如今&#xff0c;数字孪生系统凭借虚实联动的核心能力&#xff0c;为汽车工厂打造预测…

iceberg1.2.0 修改表与覆盖写

版本iceberg 1.2.0修改表只支持HiveCatalog表修改表属性&#xff0c;Iceberg表属性和Hive表属性存储在HMS中是同步的修改外部表删表时是否删除数据的表属性&#xff0c;这里是修改为删除表时不删除数据alter table iceberg_test1 set TBLPROPERTIES(external.table.purgeFALSE)…

Mini-Omni: Language Models Can Hear, Talk While Thinking in Streaming

2024.8tsinghuamethodwhisper encoder: whisper smallLLM Qwen0.5b init预测方式&#xff1a;text 7*audio token&#xff0c; parallel generation的方式预测&#xff0c;delay-step1----先预测文本token&#xff0c;再预测SNAC 第一级码本&#xff0c;然后序列化的逐渐预测后…

【MATLAB例程】基于UKF的IMM例程,模型使用CA(匀加速)和CT(协调转弯)双模型,二维环境下的轨迹定位。附代码下载链接

本文介绍的MATLAB程序可以实现&#xff1a;基于交互式多模型&#xff08;IMM&#xff09;的无迹卡尔曼滤波&#xff08;UKF&#xff09;方法&#xff0c;用于二维平面中目标的运动状态估计。该算法结合了两个运动模型&#xff1a;匀速直线模型&#xff08;CV&#xff09;和匀速…

工厂智慧设备检测:多模态算法提升工业安全阈值

工厂智慧设备检测&#xff1a;从技术突破到场景化落地在工业4.0与智能制造的双重驱动下&#xff0c;工厂设备检测正经历从人工巡检到智能化监控的颠覆性变革。传统检测方式受限于人力成本、环境干扰及响应延迟&#xff0c;难以满足现代工厂对安全性、效率与可持续性的要求。而基…

复现论文《地形遮挡对GNSS干扰范围影响的高效仿真算法》

地形遮挡对GNSS干扰范围影响的高效仿真算法 1. 论文标题 论文标题为《地形遮挡对GNSS干扰范围影响的高效仿真算法》 2. 内容概括 该论文提出了一种高效计算地形遮挡对全球导航卫星系统(GNSS)干扰源干扰范围影响的新算法。传统基于视线可视域分析的方法存在大量冗余计算,本…

图论(2)算法之拓扑排序介绍

目录 一、什么是拓扑排序&#xff1f; 二、拓扑排序的算法实现 1 BFS算法实现 &#xff08;1&#xff09;算法思路 &#xff08;2&#xff09; 代码实现&#xff08;Java&#xff09; 2 DFS算法实现 &#xff08;1&#xff09;算法思路 &#xff08;2&#xff09; 代码实…