每日一题——Python实现PAT甲级1144 The Missing Number(举一反三+思想解读+逐步优化)四千字好文


一个认为一切根源都是“自己不够强”的INTJ

个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数

Python-3.12.0文档解读

目录

我的写法

时间复杂度分析

空间复杂度分析

总体空间复杂度:O(N)

总结

我要更强

时间复杂度分析

空间复杂度分析

总结

哲学和编程思想

举一反三


题目链接

我的写法

# 接收一个整数N,表示输入的数字个数
N = int(input())# 从输入中读取N个整数,并将它们转换为集合以去除重复项
nums = set(map(int, input().split()))# 找出集合中的最大值
max_num = max(nums)# 如果集合中的最大值小于等于0,那么返回1
if max_num <= 0:print('1')raise SystemExit(0)  # 提前终止程序,因为我们已经找到了答案# 从1到最大值之间查找缺失的正整数
for i in range(1, max_num):if i not in nums:  # 如果当前数i不在集合中,输出这个数print(i)raise SystemExit(0)  # 提前终止程序,因为我们已经找到了答案# 如果1到最大值之间的所有正整数都在集合中,返回最大值+1
print(max_num + 1)

这段代码实现了查找从1开始的最小正整数,该整数不在给定的整数集合中。下面是对这段代码的详细点评和分析:

时间复杂度分析

  • 输入处理:O(N)
    • 将N个数字读取并转换为集合需要O(N)时间。
  • 查找最大值:O(N)
    • 查找集合中的最大值需要遍历所有元素,时间复杂度为O(N)。
  • 检查缺失的正整数:O(max_num)
    • 在最坏情况下,需要从1检查到 max_num,每次检查集合中是否存在某个整数的时间为O(1),因此这一部分的时间复杂度为O(max_num)。
  • 总体时间复杂度:O(N + max_num)
  • 由于 max_num 最多不会超过N,因此时间复杂度可以表示为O(N)(假设输入的N个数字都是正数且没有重复)。

空间复杂度分析

  • 输入处理:O(N)
    • 输入N个数字并存储到集合中,需要O(N)的空间。
  • 其他部分:
  • 使用了几个常数级别的额外变量如 max_num 和 i,这些变量的空间复杂度为O(1)。

总体空间复杂度:O(N)

总结

这段代码高效地查找了最小的缺失正整数,逻辑清晰,处理了多种可能的输入情况。时间复杂度为O(N),空间复杂度也是O(N),对于一般的输入规模是可以接受的。此外,使用集合来存储输入数据,可以快速地进行查找操作,进一步优化了性能。唯一需要注意的是,在极端情况下,如果输入的数字范围非常大,可能会导致较高的空间开销。


我要更强

为了优化时间复杂度和空间复杂度,我们可以考虑以下几个策略:

  1. 使用数组代替集合:如果输入的数字范围有限,可以使用数组来标记数字是否出现,这样可以减少空间使用。
  2. 只关注正整数:我们只关心正整数的缺失,因此可以忽略非正整数,这样可以减少不必要的检查。
  3. 原地修改数组:使用输入的数组本身来标记数字是否出现,这样可以避免额外的空间使用。

下面是使用这些策略优化后的代码:

# 读取输入的数字个数
N = int(input())# 读取输入的数字,并转换为列表
nums = list(map(int, input().split()))# 使用一个数组来标记1到N之间的数字是否出现
# 初始化所有位置为False,表示数字未出现
present = [False] * N# 遍历输入的数字,如果数字在1到N之间,则标记为True
for num in nums:if 1 <= num <= N:present[num - 1] = True# 遍历标记数组,找到第一个未被标记的位置,即缺失的最小正整数
for i in range(N):if not present[i]:print(i + 1)raise SystemExit(0)# 如果所有位置都被标记,则缺失的最小正整数是N+1
print(N + 1)

时间复杂度分析

  • 输入处理:O(N)
  • 标记数字:O(N)
  • 查找缺失的正整数:O(N)
  • 总体时间复杂度:O(N)

空间复杂度分析

  • 标记数组:O(N)
  • 总体空间复杂度:O(N)

总结

这段代码通过使用一个额外的数组来标记数字是否出现,优化了空间复杂度。同时,由于只关注1到N之间的数字,因此可以忽略输入中的非正整数,减少了不必要的检查。这种方法在输入数字的范围有限时非常有效,特别是在输入的数字都是正整数且范围不大于N时,可以达到O(N)的时间复杂度和空间复杂度。


哲学和编程思想

这些优化方法体现了以下哲学和编程思想:

  1. KISS原则(Keep It Simple, Stupid):
    • 代码简洁明了,避免不必要的复杂性。例如,使用数组来标记数字是否出现,而不是使用更复杂的数据结构。
  2. YAGNI原则(You Ain't Gonna Need It):
    • 只实现当前需要的功能,不预先实现未来可能需要的功能。在代码中,我们只处理了当前输入的数字,没有预先考虑更大范围的数字。
  3. 空间与时间的权衡(Space-Time Tradeoff):
    • 在空间和时间之间做出权衡。使用额外的数组来标记数字是否出现,虽然增加了空间复杂度,但减少了时间复杂度,因为可以直接在O(1)时间内检查数字是否出现。
  4. 局部性原理(Principle of Locality):
    • 利用数据的局部性,假设输入的数字集中在一定的范围内。通过限制标记数组的大小为N,我们假设缺失的正整数不会超过N,这在很多实际情况下是合理的。
  5. 抽象与具体化:
    • 将问题抽象为更具体的形式。例如,将查找缺失的最小正整数问题抽象为在数组中查找第一个未被标记的位置。
  6. 优化与效率:
    • 追求代码的效率。通过原地修改数组和使用数组标记,我们减少了不必要的内存分配和数据复制,提高了程序的执行效率。
  7. 问题分解:
    • 将复杂问题分解为更小的、可管理的部分。在代码中,我们将问题分解为读取输入、标记数字和查找缺失数字三个部分。
  8. 算法优化:
    • 选择合适的算法来解决问题。在这个例子中,我们选择了基于数组的标记算法,这是一种简单而高效的方法。
  9. 数据驱动:
  • 根据数据的特性来设计解决方案。由于我们假设输入的数字都是正整数且范围不大于N,因此我们可以设计一个基于这个假设的优化方案。

通过这些哲学和编程思想的应用,能够设计出更加高效、简洁且易于理解的代码。这些思想不仅适用于这个特定的例子,也适用于更广泛的编程和软件开发领域。


举一反三

基于上述哲学和编程思想,以下是一些技巧和策略,可以帮助在编程和问题解决中举一反三:

  1. 简化问题:
    • 在开始编码之前,尝试简化问题。去掉非必要的部分,专注于核心需求。
    • 使用简单的数据结构和算法,避免过早优化。
  2. 避免过度设计:
    • 不要预先实现不需要的功能。根据实际需求逐步构建系统。
    • 保持代码的灵活性和可扩展性,但只在必要时进行扩展。
  3. 权衡时间和空间:
    • 在设计算法时,考虑时间和空间的平衡。有时候,牺牲一点空间可以显著减少时间复杂度。
    • 分析问题的特性,选择最合适的数据结构和算法。
  4. 利用局部性原理:
    • 如果数据具有局部性,考虑使用缓存或预取技术来提高性能。
    • 在处理大量数据时,考虑数据的分块处理,以减少内存使用和提高处理速度。
  5. 抽象问题:
    • 将复杂问题分解为更小的、可管理的部分。每个部分应该有一个清晰的目标和接口。
    • 使用抽象数据类型(ADTs)来隐藏实现细节,提高代码的可读性和可维护性。
  6. 追求效率:
    • 在编码时,始终考虑性能。避免不必要的循环和递归,减少函数调用的开销。
    • 使用合适的数据结构来存储和操作数据,例如使用哈希表进行快速查找。
  7. 问题分解:
    • 将大问题分解为小问题,逐步解决。每个小问题解决后,再整合起来解决整个问题。
    • 使用模块化和分层设计,将代码组织成易于管理和测试的单元。
  8. 算法优化:
    • 学习和掌握常见的算法和数据结构,了解它们的时间和空间复杂度。
    • 在解决问题时,尝试找到最优的算法,或者对现有算法进行改进。
  9. 数据驱动:
  • 分析数据的特性,根据数据的特点选择或设计合适的算法。
  • 在处理数据密集型任务时,考虑数据预处理和后处理步骤,以提高算法的效率。

通过应用这些技巧和策略,可以在编程和问题解决中更加灵活和高效。记住,编程不仅仅是写代码,更是一种思考和解决问题的艺术。


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

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

相关文章

端口映射工具下载?

天联是一款强大的端口映射工具&#xff0c;它能够帮助用户实现远程数据采集管理、异地统一管理、随时随地协同办公等多种场景的应用。无论您是医药、餐饮、商超等零售行业的企业&#xff0c;还是需要使用OA、CRM、ERP、财务进销存等系统的企业&#xff0c;甚至是使用视频监控设…

适用于世界上最先进的医疗应用的高压电阻器

我们的电阻器专为用于医疗诊断、治疗和预防的各种产品而设计。从小型植入式和非侵入性设备到大型诊断成像设备&#xff0c;医疗制造商之所以选择 EAK电阻器&#xff0c;是因为操作环境是高电压和磁场&#xff0c;准确性和稳定性至关重要。 EAK 专有的精密打印技术生产出非常适…

如何应对 CentOS 的停更?

文章目录 如何应对 CentOS 的停更&#xff1f;Linux发行版CentOS停更后&#xff0c;我们可选的替代品RHEL LinuxRocky Linux公有云 LinuxDebian 系 Linux 如何应对 CentOS 的停更&#xff1f; Linux发行版 Linux内核是开源的&#xff0c;任何人都可以获取源代码&#xff0c;进…

嵌入式开发实验项目【基于Arduino的智能循迹小车】步进电机版本(含完整可执行详细代码)| 另附:测试行进传感器可用性,测试小车轱辘/轮胎是否可用

“真正的光明决不是永没有黑暗的时间,只是永不被黑暗所掩蔽罢了。真正的英雄决不是永没有卑下的情操,只是永不被卑下的情操所屈服罢了。” 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔…

Hi3861 OpenHarmony嵌入式应用入门--启动流程

目录 BootLoader的启动与运行 Hi3861 RiSC-V boot 启动文件介绍 Loaderboot 启动过程 Flashboot代码介绍 printf串口配置 内核启动任务 BootLoader的启动与运行 Hi3861 RiSC-V boot 启动文件介绍 - Hi3861 的引导程序分为两部分&#xff0c;一部分是在芯片出厂时已经固…

Redis-数据结构-跳表详解

Redis概述 Redis-数据结构-跳表详解 跳表&#xff08;Skip List&#xff09;是一种基于并联的链表结构&#xff0c;用于在有序元素序列中快速查找元素的数据结构。 Redis 中广泛使用跳表来实现有序集合&#xff08;Sorted Set&#xff09;这一数据结构。 1.跳表的基本概念和…

【源码】Spring事务之事务失效及原理

Spring事务 1、【源码】SpringBoot事务注册原理 2、【源码】Spring Data JPA原理解析之事务注册原理 3、【源码】Spring Data JPA原理解析之事务执行原理 4、【源码】SpringBoot编程式事务使用及执行原理 5、【源码】Spring事务之传播特性的详解 6、【源码】Spring事务之…

搜索与人工智能相结合如何解决企业数据问题?

作者&#xff1a;来自 Elastic Fermi Fang 企业数据是好处还是负担&#xff1f; 组织正被数据淹没 —— 从安全事件日志和应用程序错误消息到物联网指标和帮助中心常见问题解答。这些丰富的信息通常存在于孤立的孤岛中&#xff0c;在整合这些信息以提升客户体验、提高运营弹性…

thinkphp5使用模型删除与复杂查询EXP

模型删除 应用软删除 表中需要有字段&#xff0c;deletetime 模型中使用下面方法 use SoftDelete;protected $deleteTime delete_time;真实删除 // 软删除 User::destroy(1); // 真实删除 User::destroy(1,true); $user User::get(1); // 软删除 $user->delete(); // 真…

js 实现将后端请求来的 Blob 数据保存到用户选择的任意目录

js实现将后端请求来的 Blob 数据保存到用户选择的任意目录 实现方式 实现方式 实现方式是使用 window 的 showSaveFilePicker 方法。Window 接口的 showSaveFilePicker() 方法用于显示一个文件选择器&#xff0c;以允许用户保存一个文件。可以选择一个已有文件覆盖保存&#xf…

基于Java+Swing贪吃蛇小游戏(含课程报告)

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

兼容MacOS和FreeBSD软件包的开源ravynOS操作系统

ravynOS 是一个新型的操作系统项目&#xff0c;致力于在 x86-64&#xff08;终极目标是同时实现 ARM&#xff09;平台上提供与 macOS 类似的体验和兼容性。它基于坚若磐石的 FreeBSD、现有的开源代码和锦上添花的新代码构建。 主要设计目标&#xff1a; 与 macOS 应用程序的源…

语音质量评价方法之MOS

引言 在语音增强、语音合成、语音转换、声音转换、语音克隆、语音修复等等领域&#xff0c;常常要对输出的语音进行评价。对语音的质量评价一般关注两个方面&#xff0c;即主观评价和客观评价。主观评价就是人凭借听觉感受对语音进行打分&#xff0c;客观评价比较广泛&#xf…

学生成绩评分 - Scala

文章目录 一、第1关&#xff1a;对学生成绩进行评分 一、第1关&#xff1a;对学生成绩进行评分 实训目标 掌握 Scala 中运算符嵌套的使用 了解 if-else if-else 语句的使用 实训分析 利用条件运算符的嵌套来完成此题&#xff1a;学习成绩 150 - 90 分的同学成绩评分为&#…

【JVM结构、JVM参数、JVM垃圾回收】

JVM&#xff1a;Java Virtual Machine java虚拟机 虚拟机&#xff1a;使用软件技术模拟出与具有完整硬件系统功能、运行在一个隔离环境中的计算机系统。 JVM官方文档&#xff1a;https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java 一些命令 javac 将文件编…

常用算法及参考算法 (1)累加 (2)累乘 (3)素数 (4)最大公约数 (5)最值问题 (6)迭代法

常用算法及参考算法 &#xff08;1&#xff09;累加 &#xff08;2&#xff09;累乘 &#xff08;3&#xff09;素数 &#xff08;4&#xff09;最大公约数 &#xff08;5&#xff09;最值问题 &#xff08;6&#xff09;迭代法 1. 累加 #include <stdio.h>int main() {…

上海亚商投顾:沪指缩量调整 PCB概念股持续爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 大小指数昨日走势分化&#xff0c;沪指全天震荡调整&#xff0c;创业板指午后涨超1%。消费电子板块全天强势&a…

【ARM】MDK Debug模式下Disassembly窗口介绍

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 主要了解Disassembly窗口中包含的内容&#xff0c;和如何利用Disassembly中的内容了解程序的存储和调用情况。 2、 问题场景 对于Disassembly窗口中具体包含的内容不了解&#xff0c;无法合理地应用Disassembly窗口…

Docker的基本操作 及 容器与外部机互相通讯(持续更新中)

Docker入门&#xff1a; Docker 入门教程 - 阮一峰的网络日志 (ruanyifeng.com)docker入门&#xff0c;这一篇就够了。-CSDN博客Docker 容器使用 | 菜鸟教程 (runoob.com)Docker自定义网络和运行时指定IP_docker run ip-CSDN博客 基本命令 链接&#xff1a;docker入门&#…

希尔排序-C语言版本

前言 从希尔开始&#xff0c;排序的速度就开始上升了&#xff0c;这里的排序开始上一个难度了&#xff0c;当然难一点的排序其实也不是很难&#xff0c;当你对于插入排序了解的足够深入的时候&#xff0c;你会发现其实希尔就是插入的异形&#xff0c;但是本质上还是一样的 希尔…