LeetCode题目73:矩阵置零

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
欢迎加入社区:码上找工作
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
python源码解读
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

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

输入格式
  • matrix:一个二维整数数组。
输出格式
  • 不返回任何内容,但要将 matrix 中的行和列置零。

示例

示例 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]
]

方法一:使用额外存储空间

解题步骤
  1. 标记零的位置:遍历整个矩阵,使用两个集合来分别记录哪些行和哪些列需要被置零。
  2. 置零行和列:再次遍历矩阵,根据行和列的集合来置零对应的行和列。
完整的规范代码
def setZeroes(matrix):"""使用额外存储空间的方法来置零矩阵:param matrix: List[List[int]], 输入的二维矩阵"""rows, cols = set(), set()m, n = len(matrix), len(matrix[0])for i in range(m):for j in range(n):if matrix[i][j] == 0:rows.add(i)cols.add(j)for i in range(m):for j in range(n):if i in rows or j in cols:matrix[i][j] = 0# 示例调用
matrix = [[1,1,1],[1,0,1],[1,1,1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1,0,1],[0,0,0],[1,0,1]]
算法分析
  • 时间复杂度:(O(m * n)),需要两次遍历整个矩阵。
  • 空间复杂度:(O(m + n)),使用了额外空间来存储需要置零的行和列。

方法二:使用常数空间的优化

解题步骤
  1. 原地修改:使用矩阵的第一行和第一列来记录该行或列是否需要置零。
  2. 单独标记第一行和第一列:因为第一行和第一列共用 matrix[0][0],所以需要一个额外的标记来区分第一列是否需要置零。
  3. 二次遍历填充:第一次从底部开始遍历以避免提前修改第一行或第一列的值,第二次从顶部开始正常遍历并使用第一行和第一列的标记来置零。
完整的规范代码
def setZeroes(matrix):"""使用常数空间的方法来置零矩阵:param matrix: List[List[int]], 输入的二维矩阵"""m, n = len(matrix), len(matrix[0])first_col = any(matrix[i][0] == 0 for i in range(m))for i in range(m):for j in range(1, n):  # 从第二列开始if matrix[i][j] == 0:matrix[i][0] = matrix[0][j] = 0for i in range(m - 1, -1, -1):for j in range(1, n):if matrix[i][0] == 0 or matrix[0][j] == 0:matrix[i][j] = 0if first_col:matrix[i][0] = 0# 示例调用
matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]
]
setZeroes(matrix)
print(matrix)  # 输出: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
算法分析
  • 时间复杂度:(O(m * n)),两次遍历整个矩阵。
  • 空间复杂度:(O(1)),除了几个用于标记的变量外,没有使用额外的空间。

方法三:改进的标记方法

解题步骤
  1. 单次遍历:在第一次遍历的同时,直接在第一行和第一列上进行标记。
  2. 尾部处理:利用第一行和第一列的标记进行最后的置零处理。
完整的规范代码
def setZeroes(matrix):"""改进的标记方法来置零矩阵:param matrix: List[List[int]], 输入的二维矩阵"""m, n = len(matrix), len(matrix[0])for i in range(m):if matrix[i][0] == 0:first_col_zero = Truefor j in range(1, n):if matrix[i][j] == 0:matrix[i][0] = matrix[0][j] = 0for i in range(m - 1, -1, -1):for j in range(n - 1, 0, -1):if matrix[i][0] == 0 or matrix[0][j] == 0:matrix[i][j] = 0if first_col_zero:matrix[i][0] = 0# 示例调用
matrix = [[1,1,1],[1,0,1],[1,1,1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1,0,1],[0,0,0],[1,0,1]]
算法分析
  • 时间复杂度:(O(m * n)),只有一次遍历,但每个元素都被检查。
  • 空间复杂度:(O(1)),使用了原矩阵的第一行和第一列作为标记,没有额外空间。

方法四:首尾标记优化

解题步骤
  1. 首尾行列标记:分别使用矩阵的首行和尾行进行置零标记。
  2. 中间处理:根据首尾标记决定中间行列是否需要置零。
完整的规范代码
def setZeroes(matrix):"""首尾标记优化方法来置零矩阵:param matrix: List[List[int]], 输入的二维矩阵"""m, n = len(matrix), len(matrix[0])first_row_zero = any(matrix[0][j] == 0 for j in range(n))last_row_zero = any(matrix[m-1][j] == 0 for j in range(n))for i in range(1, m-1):for j in range(1, n-1):if matrix[i][j] == 0:matrix[i][0] = matrix[0][j] = 0for i in range(1, m-1):for j in range(1, n-1):if matrix[i][0] == 0 or matrix[0][j] == 0:matrix[i][j] = 0if first_row_zero:for j in range(n):matrix[0][j] = 0if last_row_zero:for j in range(n):matrix[m-1][j] = 0# 示例调用
matrix = [[1,1,1],[1,0,1],[1,1,1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1,0,1],[0,0,0],[1,0,1]]
算法分析
  • 时间复杂度:(O(m * n)),通过两次遍历完成。
  • 空间复杂度:(O(1)),使用首尾行列作为标记,不需要额外空间。

方法五:位运算标记法

解题步骤
  1. 使用位运算标记:通过位运算标记哪些行和列需要置零。
  2. 处理置零:根据标记,决定如何置零矩阵中的行和列。
完整的规范代码
def setZeroes(matrix):"""位运算标记法来置零矩阵:param matrix: List[List[int]], 输入的二维矩阵"""row_flag, col_flag = 0, 0m, n = len(matrix), len(matrix[0])for i in range(m):for j in range(n):if matrix[i][j] == 0:row_flag |= (1 << i)col_flag |= (1 << j)for i in range(m):for j in range(n):if row_flag & (1 << i) or col_flag & (1 << j):matrix[i][j] = 0# 示例调用
matrix = [[1,1,1],[1,0,1],[1,1,1]
]
setZeroes(matrix)
print(matrix)  # 输出: [[1,0,1],[0,0,0],[1,0,1]]
算法分析
  • 时间复杂度:(O(m * n)),必须遍历整个矩阵来标记和处理。
  • 空间复杂度:(O(1)),使用固定数量的位标记。

不同算法的优劣势对比

特征方法一:额外存储方法二:常数空间优化方法三:改进标记方法四:首尾标记优化方法五:位运算标记
时间复杂度(O(m * n))(O(m * n))(O(m * n))(O(m * n))(O(m * n))
空间复杂度(O(m + n))(O(1))(O(1))(O(1))(O(1))
优势简单直观空间高效一次遍历即可特殊行列单独处理位操作快速且节省空间
劣势空间占用较大需要复杂的标记逻辑实现稍复杂实现稍复杂对位操作要求较高,可能增加实现复杂性

应用示例

图像处理:在图像处理中,可能需要对图像矩阵进行操作,类似于置零的操作可用于快速清除某些区域。

数据清洗:在数据预处理阶段,需要将包含无效数据的行和列清除,这些算法可直接应用于清洗包含缺失值的数据集。

软件开发:在软件开发中,处理大规模数据时常需要类似的矩阵操作来快速应用某些条件,这些方法提供了多种实现这一功能的方式。

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

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

相关文章

Amazon云计算AWS之[4]非关系型数据库服务SimpleDB和DynamoDB

文章目录 简介非关系型VS关系数据库SimpleDB域条目属性值SimpleDB的使用 DynamoDBSimpleDB VS DynamoDB 简介 非关系型数据库服务主要用于存储结构化的数据&#xff0c;并为这些数据提供查找、删除等基本的数据库功能。AWS中提供的非关系型数据库主要包括SimpleDB和DynamoDB …

(学习日记)2024.04.20:UCOSIII第四十八节:各文件功能概览

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

牛客网:S老师的公式 ← 取模运算

【题目来源】https://ac.nowcoder.com/acm/contest/76652/A【题目描述】 S 老师丢给你了一个简单的数学问题&#xff1a; 求 。 请你求出答案。【输入格式】 一行一个整数 n (1≤n≤10^6)。【输出格式】 一行一个整数表示答案。【说明】 例如&#xff0c;若n3&#xff0c;则本题…

设计模式-责任链模式(Chain of Responsibility Pattern)结构|原理|优缺点|场景|示例

设计模式&#xff08;分类&#xff09; 设计模式&#xff08;六大原则&#xff09; 创建型&#xff08;5种&#xff09; 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型&#xff08;7种&#xff09; 适配器…

对于C# 任务并行库(TPL)的一些理解

C# 的任务并行库&#xff08;Task Parallel Library&#xff0c;TPL&#xff09;是 .NET 框架的一个部分&#xff0c;它提供了一组丰富的API&#xff0c;旨在简化并行编程&#xff0c;使开发人员能够更容易地构建可以利用多核处理器优势的高性能应用程序。TPL 的设计目的是减少…

【redis】Redis数据类型(一)——String类型(包含redis通用命令)

目录 Redis通用命令String类型常用的操作命令一些特殊命令详解setnx示例使用 setrange示例 mset示例 msetnx示例 append示例 getset示例 incr示例使用1.计数器2.限速器 bitcount示例使用&#xff1a;使用 bitmap 实现用户上线次数统计性能 String类型String类型简介String类型的…

统一威胁情报如何赋能SOC应对复杂威胁?

安全运营中心&#xff08;SOC&#xff09;是组织网络安全战略的核心组成部分&#xff0c;扮演着至关重要的角色。其负责实时监控整个IT基础设施&#xff0c;以检测、响应和预防各类网络安全威胁。网络安全威胁日益复杂且多变的数字化时代&#xff0c;攻击平面泛化、基础设施复杂…

GET 和 POST 请求方式的区别

GET 和 POST 请求方式的区别 GET请求和POST请求在HTTP通信中有着不同的用途和限制。以下是两者之间的一些主要区别&#xff1a; URL可见性 GET请求的参数直接附加在URL后面&#xff0c;因此可以被用户看到POST请求的参数位于请求体中&#xff0c;对URL参数是不可见的 数据传输方…

C#技巧之窗体去鼠标化

简介 在窗体程序中不用鼠标&#xff0c;直接使用键盘完成想要的操作。 实现的方法有两种&#xff0c;一种是使用键盘上的Tab键使控件获得焦点&#xff0c;然后用enter键触发该控件上的事件&#xff08;一般为click事件&#xff09;。另一种是&#xff0c;为控件添加快捷键&am…

新手去做视频号小店常见的问题解答!全篇干货!建议收藏!

大家好&#xff0c;我是电商小V 视频号小店现在可以说是越来越火&#xff0c;在创业者的人群中被提及的次数也是越来越高&#xff0c;导致这种情况的原因就是&#xff0c;新项目&#xff0c;正处于红利期&#xff0c;现在去做是可以很轻易分到属于自己的一杯羹&#xff0c;就是…

Android 蓝牙无法发送或接收某些类型文件

Android 蓝牙应用使得用户能够在蓝牙设备之间进行文件传输。用户可以通过蓝牙连接两台设备&#xff0c;并在它们之间传输文件&#xff0c;如照片、音乐、视频等。这对于用户来说是非常便利的&#xff0c;无需使用数据线或互联网连接&#xff0c;可以直接在附近的设备之间进行文…

基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“大学生社团活动平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统结构图 管理员登录界面图 管理员功能界…

C#基础|数组的使用、字符串的分隔与连接

哈喽,你好,我是雷工! 01 数组概念 数组是一个变量,用来存储“相同数据类型”的“一组数据”。 02 数组与普通变量的区别 声明一个变量,就是在内存空间分配一块儿合适的空间; 声明一个数组,就是在内存空间分配一串儿连续的空间。 03 数组基本要素 标识符:数组的名…

SpringCloud中网关-详解、案例(代码)

简介&#xff1a;在Spring Cloud中&#xff0c;网关的角色是非常重要的&#xff0c;它负责整个系统的入口流量&#xff0c;并且可以处理路由、过滤、协议转换等操作 目录 1、网关的技术实现 1.1 网关功能 1.2 网关的形式 2、网关实现步骤 2.1 添加相关依赖 2.2 创建此mod…

【算法刷题 | 贪心算法05】4.27(K次取反后最大化的数组和、加油站)

文章目录 8.K次取反后最大化的数组和8.1题目8.2解法&#xff1a;贪心8.2.1贪心思路8.2.2代码实现 9.加油站9.1题目9.2解法&#xff1a;贪心9.2.1贪心思路9.2.2代码实现 8.K次取反后最大化的数组和 8.1题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数…

【深度学习-番外1】Win10系统搭建VSCode+Anaconda+Pytorch+CUDA深度学习环境和框架全过程

专栏的老读者们都知道&#xff0c;以前的文章以使用MATLAB的为多。 不过后续陆续开始展开深度学习算法的应用&#xff0c;就会逐渐引入Python语言了&#xff08;当然MATLAB的代码也会同步更新&#xff09;&#xff0c;这是由于在深度学习领域&#xff0c;Python应用更为广泛。…

6.比较含退格的字符串(力扣字符串)(两种解法:字符串操作,栈)

目录 题目链接 法一&#xff1a;普通字符串操作 法二&#xff1a;栈操作 题目链接 . - 力扣&#xff08;LeetCode&#xff09; 法一&#xff1a;普通字符串操作 用len1记录目前s的字符个数&#xff0c;len2记录目前t的字符个数 如果不是#&#xff0c;则s[len1] s[i] 如果是…

解决Android Studio安卓开发写入文件问题

有很多小伙伴想把文件写进安卓系统储存失败&#xff0c;类似下面的代码 val file File("account.txt")val writer BufferedWriter(FileWriter(file))writer.use {it.write(username "," password)} 用java方式写入读出文件但是显示成功但是找不到文件…

Linux--自主编写shell

目录 准备知识 shell原理 shell与用户互动的过程 实现shell 0.用到的头文件和宏定义 1.首先我们需要自己输出一个命令行 2.获取用户命令行字符 3.命令行字符串分割 4.执行命令 5.设置循环 6.检测内建命令 7.完善细节--获取工作目录而非路径 准备知识 Linux--环境…

Linux系统安全与应用【二】

目录 1.开关机安全控制 1.2 实例&#xff1a;GRUB 菜单设置密码 2.终端登录安全控制 2.1 限制root只在安全终端登录 ​3.弱口令检测 3.1 Joth the Ripper,JR​编辑 4.网络端口扫描 4.1 nmap命令 1.开关机安全控制 1.1 GRUB限制 限制更改GRUB引导参数 通常情况下在系统…