Python算法题集_矩阵置零

 Python算法题集_矩阵置零

  • 题73:矩阵置零
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【三层循环】
    • 2) 改进版一【纵横计数器】
    • 3) 改进版二【原地算法】
  • 4. 最优算法

本文为Python算法题集之一的代码示例

题73:矩阵置零

1. 示例说明

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

示例 1:

img

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

示例 2:

img

输入: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 == matrix[0].length
  • 1 <= m, n <= 200
  • -231 <= matrix[i][j] <= 231 - 1

进阶:

  • 一个直观的解决方案是使用 O(m*n) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m+n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗

2. 题目解析

- 题意分解

  1. 原地算法是一个使用辅助的数据结构对输入进行转换的算法。它允许有少量额外的存储空间来储存辅助变量。当算法运行时,输入通常会被输出覆盖。原地算法仅通过替换或交换元素来更新输入序列。不是原地算法有时候称为非原地(not-in-place)或者不得其所(out-of-place)
  2. 本题为将矩阵中的零进行行列填充
  3. 本题的主要计算有2处,1是元素遍历,2是行列填充
  4. 基本的解法是三层循环,读取到任何一个元素为零均进行一次行填充、一次列填充,所以基本的时间算法复杂度为O(n^3)

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集数量

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 必须对行列进行全扫描以确定所有0,任何一个行/列只要出现一个0就不需要再扫,可以用调度用的数据结构优化

    2. 调度用的数据可以存在输入的矩阵中,实现原地算法【空间复杂度O(1)】


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题很难超时,本地化超时测试用例自己生成,详见【最优算法章节】

3. 代码展开

1) 标准求解【三层循环】

三层循环,超过22%在这里插入图片描述

丧心病狂的三层循环,可谓可算尽算,不漏过任何角落,依旧没有超时;看起来超时测试用例还是不给力

import CheckFuncPerf as cfpdef setZeroes_base(matrix):import copymatrixcopy = copy.deepcopy(matrix)ilenrow, ilencol = len(matrix), len(matrix[0])for iIdx in range(ilenrow):for jIdx in range(ilencol):if matrixcopy[iIdx][jIdx] == 0:for kIdx in range(ilenrow):matrix[kIdx][jIdx] = 0for kIdx in range(ilencol):matrix[iIdx][kIdx] = 0import random
matrix = []
for iIdx in range(1000):matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_base, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 setZeroes_base 的运行时间为 62147.93 ms;内存使用量为 336.00 KB 执行结果 = None

2) 改进版一【纵横计数器】

一个横向数组、一个纵向数组,检测需要置零的行列,算法相当于O(n^2) 君临天下,九九归一【超越99%】在这里插入图片描述

import CheckFuncPerf as cfpdef setZeroes_ext1(matrix):ilenrow, ilencol = len(matrix), len(matrix[0])icmdrow, icmdcol = [0] * ilenrow, [0] * ilencolfor iIdx in range(ilenrow):for jIdx in range(ilencol):if matrix[iIdx][jIdx] == 0:icmdrow[iIdx] = 1icmdcol[jIdx] = 1for iIdx in range(ilenrow):if icmdrow[iIdx] > 0:for jIdx in range(ilencol):matrix[iIdx][jIdx] = 0for iIdx in range(ilencol):if icmdcol[iIdx] > 0:for jIdx in range(ilenrow):matrix[jIdx][iIdx] = 0import random
matrix = []
for iIdx in range(1000):matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_ext1, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 setZeroes_ext1 的运行时间为 152.05 ms;内存使用量为 8.00 KB 执行结果 = None

3) 改进版二【原地算法】

在传入的矩阵中保存横向数组、纵向数组,因此空间复杂度为O(1) 表现优异,超过90%在这里插入图片描述

import CheckFuncPerf as cfpdef setZeroes_ext2(matrix):ilenrow, ilencol = len(matrix), len(matrix[0])icmdrow, icmdcol = -1, -1bNotfind = Truefor iIdx in range(ilenrow):for jIdx in range(ilencol):if matrix[iIdx][jIdx] == 0:if bNotfind:icmdrow = iIdxicmdcol = jIdxbNotfind = Falsematrix[icmdrow][jIdx] = 0matrix[iIdx][icmdcol] = 0if bNotfind:returnfor iIdx in range(ilenrow):if iIdx != icmdrow:if matrix[iIdx][icmdcol] == 0:for jIdx in range(ilencol):if jIdx != icmdcol:matrix[iIdx][jIdx] = 0for iIdx in range(ilencol):if iIdx != icmdcol:if matrix[icmdrow][iIdx] == 0:for jIdx in range(ilenrow):if jIdx != icmdrow:matrix[jIdx][iIdx] = 0for iIdx in range(ilenrow):matrix[iIdx][icmdcol] = 0for iIdx in range(ilencol):matrix[icmdrow][iIdx] = 0import random
matrix = []
for iIdx in range(1000):matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_ext2, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 setZeroes_ext2 的运行时间为 508.10 ms;内存使用量为 0.00 KB 执行结果 = None

4. 最优算法

根据本地日志分析,最优算法为第2种setZeroes_ext1

import random
matrix = []
for iIdx in range(1000):matrix.append([random.randint(0,1) for x in range(1000)])# 算法本地速度实测比较
函数 setZeroes_base 的运行时间为 62147.93 ms;内存使用量为 336.00 KB 执行结果 = None
函数 setZeroes_ext1 的运行时间为 152.05 ms;内存使用量为 8.00 KB 执行结果 = None
函数 setZeroes_ext2 的运行时间为 508.10 ms;内存使用量为 0.00 KB 执行结果 = None

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

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

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

相关文章

python爬虫5

1.selenium交互 无页面浏览器速度更快 #配置好的自己不用管 from selenium import webdriverfrom selenium.webdriver.chrome.options import Optionschrome_options Options()chrome_options.add_argument(‐‐headless)chrome_options.add_argument(‐‐disable‐gpu)# path…

vue不同环境配置不同打包命令

这个需求非常普遍&#xff0c;通常情况我们在开发的时候一般会有三个环境&#xff1a;开发环境、测试环境、生产环境&#xff0c;我们一步步来看下。 vue环境变量是什么&#xff1f; 指的是在不同地方&#xff08;开发环境、测试环境、生产环境&#xff09;&#xff0c;变量就…

C语言经典面试题——翻转单词顺序VS左旋转字符串

目录 1. 翻转单词顺序1.1 题目描述1.2 解法1.3 完整代码 2. 左旋转字符串2.1 题目描述2.1.1 解法一&#xff1a;2.1.2 解法二&#xff1a;2.1.2.1 strcpy2.1.2.2 strcat2.1.2.3 完整代码 2.1.3 解法三&#xff1a; 1. 翻转单词顺序 1.1 题目描述 输入一个英文句子&#xff0c;…

Docker安装RocketMQ 笔记

RocketMQ架构上主要分为四部分&#xff1a; Producer&#xff1a;消息发布的角色&#xff0c;支持分布式集群方式部署。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递&#xff0c;投递的过程支持快速失败并且低延迟。Consumer&#xff1a;消息消费的角色…

【C++】C++入门— 类与对象初步介绍

C入门 1 认识面向对象2 类的引入3 类的定义类的定义方式 4 类的访问限定符及封装访问限定符封装 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 1 认识面向对象 C语言是面向过程的&#xff0c;关注…

浅析Redis③:命令处理之数据返回Client(下)

写在前面 Redis作为我们日常工作中最常使用的缓存数据库&#xff0c;其重要性不言而喻&#xff0c;作为普通开发者&#xff0c;我们在日常开发中使用Redis&#xff0c;主要聚焦于Redis的基层数据结构的命令使用&#xff0c;很少会有人对Redis的内部实现机制进行了解&#xff0c…

109.乐理基础-五线谱-五线谱的附点、休止符、连线、延音线

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;五线谱的拍号、音符与写法-CSDN博客 上一个内容里练习的答案&#xff1a; 附点&#xff1a;写在符头的右方&#xff0c;附点的作用与简谱一样&#xff0c;延长前面音符本身时值的一半&#xff08;附点&#xff09;…

242. Valid Anagram(有效的字母异位词)

问题描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 问题分析 此问题与383. Ransom Note(赎金信)类似&#xff0c;只是字符变为了…

dubbo+sentinel最简集成实例

说明 在集成seata后&#xff0c;下面来集成sentinel进行服务链路追踪管理&#xff5e; 背景 sample-front网关服务已配置好 集成 一、启动sentinel.jar 1、官网下载 选择1:在本地启动 nohup java -Dserver.port8082 -Dcsp.sentinel.dashboard.serverlocalhost:8082 -Dp…

springcloud bus消息总线

简介 Spring Cloud Bus 配合Spring Cloud Config 使用可以实现配置的动态刷新。 Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架&#xff0c;它整合了Java的事件处理机制和消息中间件的功能。Spring Clud Bus目前支持RabbitMQ和Kafka。 Spring C…

Transformer实战-系列教程1:Transformer算法解读1

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 Transformer实战-系列教程1&#xff1a;Transformer算法解读1 Transformer实战-系列教程2&#xff1a;Transformer算法解读2 现在最火的AI内容&#xff0c;chatGPT、视觉大模…

2024年【道路运输企业安全生产管理人员】免费试题及道路运输企业安全生产管理人员模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 道路运输企业安全生产管理人员免费试题参考答案及道路运输企业安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及道路运输企业安全生产管理人员操作证已考过的学员汇总&#xff0c;相对有效帮助道路运…