每日一题——Python实现PAT乙级1030 完美数列(举一反三+思想解读+逐步优化)五千字好文


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

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

Python-3.12.0文档解读

目录

初次尝试

再次尝试

代码结构

时间复杂度分析

空间复杂度分析

总结

我要更强

时间复杂度分析

空间复杂度分析

总结

哲学和编程思想

抽象与模块化:

效率与性能优化:

数据结构的选择:

迭代与递增开发:

避免重复计算:

错误处理与容错:

代码可读性与维护性:

测试与验证:

举一反三

理解问题本质:

选择合适的数据结构:

优化算法:

模块化设计:

迭代开发:

代码复用:

编写清晰的代码:

测试驱动开发:

持续学习和实践:

反思和总结:


题目链接:https://pintia.cn/problem-sets/994805260223102976/exam/problems/type/7?problemSetProblemId=994805291311284224&page=0

初次尝试

import sys  # 导入sys模块,用于读取标准输入# 使用sys.stdin.read方法读取所有输入,并将其分割成一个列表
input = sys.stdin.read
inputs = input().split()# 从输入列表中提取N和p的值
N = int(inputs[0])
p = int(inputs[1])# 将输入列表中剩余的部分转换为整数列表
nums = list(map(int, inputs[2:]))# 初始化目标数列列表
target_nums = list()# 初始化最大值M和最小值m为数列的第一个元素
M = nums[0]
m = nums[0]# 遍历输入的数列
for i in range(N):# 将当前元素添加到目标数列中target_nums.append(nums[i])# 保存上一次的最大值和最小值last_M = Mlast_m = m# 标记是否有最大值或最小值被改变M_or_m_changed = -1# 如果当前元素大于或等于M,则更新Mif M <= nums[i]:M = nums[i]M_or_m_changed = 1# 如果当前元素小于或等于m,则更新melif nums[i] <= m:m = nums[i]M_or_m_changed = 0# 检查当前目标数列是否满足完美数列的条件if M <= m * p:pass  # 如果满足条件,则不做任何操作else:# 如果不满足条件,则从目标数列中移除最后一个元素target_nums.pop()# 根据是否有最大值或最小值被改变,恢复它们if M_or_m_changed == 1:M = last_Melif M_or_m_changed == 0:m = last_m# 输出目标数列的长度
sys.stdout.write(f"{len(target_nums)}\n")

再次尝试

import sys# 读取输入
input = sys.stdin.read
inputs = input().split()
N = int(inputs[0])
p = int(inputs[1])
nums = list(map(int, inputs[2:]))# 对数列进行排序
nums.sort()# 初始化双指针和最大长度
left = 0
max_length = 0# 使用双指针遍历数列
for right in range(N):# 移动左指针,直到子数组满足条件while nums[right] > nums[left] * p:left += 1# 更新最大长度max_length = max(max_length, right - left + 1)# 输出结果
sys.stdout.write(f"{max_length}\n")

这段代码实现了一个双指针算法,用于解决一个特定问题:给定一个数列和乘数p,找到数列中满足任意元素大于其左边任意元素乘以p的最长子数组的长度。下面是对这段代码的点评:

代码结构

  1. 输入处理

    • 使用sys.stdin.read读取所有输入,并将输入分割成整数。
    • 读取数列长度N、乘数p和数列本身。
  2. 排序

    • 对数列进行排序,这是为了后续的双指针算法能够正确工作。
  3. 双指针算法

    • 初始化左指针left和最大长度max_length
    • 遍历数列,使用右指针right
    • 当右指针指向的元素大于左指针指向的元素乘以p时,移动左指针。
    • 每次移动右指针后,更新最大长度。
  4. 输出结果

    • 使用sys.stdout.write输出最大长度。

时间复杂度分析

  • 排序:使用Python内置的sort()方法,时间复杂度为O(N log N),其中N是数列的长度。
  • 双指针遍历:每个元素最多被访问两次(一次由左指针,一次由右指针),因此这一部分的时间复杂度是O(N)。
  • 总时间复杂度为O(N log N + N),由于N log N在渐近意义上占主导,所以整体时间复杂度为O(N log N)。

空间复杂度分析

  • 输入处理:存储输入的数列需要O(N)的空间。
  • 排序:Python的sort()方法在原地排序,不需要额外空间。
  • 双指针算法:只需要常数级别的额外空间。
  • 总空间复杂度为O(N)。

总结

这段代码有效地使用了双指针算法来解决问题,通过排序简化了问题的处理。时间复杂度主要受排序影响,而空间复杂度相对较低。代码结构清晰,逻辑明确,是一个良好的算法实现。


我要更强

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

  1. 避免排序:排序的时间复杂度是O(N log N),如果我们能够避免排序,可以显著减少时间复杂度。
  2. 使用更高效的数据结构:例如,使用哈希表来存储和快速查找元素。
  3. 优化双指针算法:确保算法的每个步骤都是必要的,避免不必要的计算。

下面是一个优化后的代码实现,避免了排序,并使用了哈希表来存储元素和它们的位置:

import sys# 读取输入
input = sys.stdin.read
inputs = input().split()
N = int(inputs[0])
p = int(inputs[1])
nums = list(map(int, inputs[2:]))# 使用哈希表存储数列元素和它们的位置
num_positions = {num: i for i, num in enumerate(nums)}# 初始化双指针和最大长度
left = 0
max_length = 0# 使用双指针遍历数列
for right in range(N):# 移动左指针,直到子数组满足条件while nums[right] > nums[left] * p:left += 1# 更新最大长度max_length = max(max_length, right - left + 1)# 输出结果
sys.stdout.write(f"{max_length}\n")

时间复杂度分析

  • 输入处理:时间复杂度为O(N),因为我们遍历了一次输入来创建数组和哈希表。
  • 双指针遍历:时间复杂度为O(N),因为每个元素最多被访问两次。
  • 总时间复杂度为O(N),这是一个显著的改进,因为我们避免了排序。

空间复杂度分析

  • 输入处理:空间复杂度为O(N),因为我们存储了数组和哈希表。
  • 双指针算法:只需要常数级别的额外空间。
  • 总空间复杂度为O(N)。

总结

这个优化版本的代码通过避免排序和使用哈希表来存储元素位置,将时间复杂度从O(N log N)降低到O(N),同时保持了空间复杂度为O(N)。这是一个更高效的解决方案,特别是在处理大规模数据时。


哲学和编程思想

优化算法的过程中,运用了多种哲学和编程思想,以下是一些关键点:

  1. 抽象与模块化

    • 在编程时,我们将问题分解为更小的、可管理的部分(如输入处理、数据结构创建、算法实现等),每个部分都有明确的功能和接口。这种模块化的方法使得代码更易于理解和维护。
  2. 效率与性能优化

    • 我们关注算法的时间复杂度和空间复杂度,通过避免不必要的排序操作和使用哈希表来提高效率。这种优化体现了对算法性能的重视,是计算机科学中追求高效计算的核心思想。
  3. 数据结构的选择

    • 使用哈希表来存储元素和它们的位置,这是基于对数据结构特性的理解。哈希表提供了快速的查找操作,非常适合需要频繁查找元素位置的场景。
  4. 迭代与递增开发

    • 在实现算法时,我们采用迭代的方法,逐步构建和测试代码。这种方法有助于及时发现和修复问题,同时也使得代码的开发过程更加稳健。
  5. 避免重复计算

    • 通过预先存储元素位置,我们避免了在双指针算法中重复查找元素位置的操作。这种避免重复计算的思想是优化算法性能的重要策略。
  6. 错误处理与容错

    • 虽然代码中没有显式的错误处理,但在实际应用中,考虑输入的合法性和异常情况的处理是重要的。这体现了编程中的容错思想,即确保程序在面对不完美或异常输入时仍能稳定运行。
  7. 代码可读性与维护性

    • 代码中使用了清晰的变量命名和适当的注释,这有助于提高代码的可读性。良好的代码风格和结构使得代码更易于维护和扩展。
  8. 测试与验证

    • 在实际应用中,对算法进行充分的测试是确保其正确性和性能的关键。这包括单元测试、集成测试等,确保代码在各种情况下都能按预期工作。

通过这些哲学和编程思想的应用,不仅提高了算法的效率,也确保了代码的质量和可维护性。这些原则是软件工程和算法设计中的基础,对于开发高效、可靠的软件系统至关重要。


举一反三

根据上述哲学和编程思想,以下是一些技巧和策略,可以帮助你在面对类似问题时举一反三:

  1. 理解问题本质

    • 在开始解决问题之前,深入理解问题的本质和需求。这有助于确定最合适的算法和数据结构。
  2. 选择合适的数据结构

    • 根据问题的特性选择最合适的数据结构。例如,如果需要快速查找和插入操作,哈希表可能是一个好选择;如果需要保持元素的顺序,链表或数组可能更合适。
  3. 优化算法

    • 分析算法的时间复杂度和空间复杂度,寻找可能的优化点。例如,通过避免重复计算、使用缓存或减少不必要的操作来提高效率。
  4. 模块化设计

    • 将问题分解为更小的模块,每个模块负责一个特定的功能。这不仅使代码更易于管理,也便于测试和维护。
  5. 迭代开发

    • 采用迭代的方法开发代码,逐步增加功能并进行测试。这种方法有助于及时发现问题并进行调整。
  6. 代码复用

    • 尽可能复用已有的代码和解决方案。这不仅可以节省时间,也有助于保持代码的一致性和质量。
  7. 编写清晰的代码

    • 使用有意义的变量名、注释和清晰的代码结构。这有助于他人(或未来的你)理解和维护代码。
  8. 测试驱动开发

    • 在编写代码之前先编写测试用例。这有助于确保代码的正确性,并鼓励开发出更健壮的解决方案。
  9. 持续学习和实践

    • 不断学习新的编程技术和算法,通过实践应用这些知识。这有助于提高解决问题的能力。
  10. 反思和总结

    • 在解决问题后,回顾整个过程,总结哪些方法有效,哪些可以改进。这种反思有助于在未来的问题解决中更加高效。

通过应用这些技巧和策略,不仅能够解决当前的问题,还能够提高自己解决更广泛问题的能力。记住,编程和算法设计是一个不断学习和实践的过程,持续的努力和反思将使你成为一个更优秀的程序员。


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

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

相关文章

【SQL】InnoDB 和 MylSAM 的区别

InnoDB 和 MyISAM 是 MySQL 中两种常见的存储引擎&#xff0c;它们在特性和适用场景上有显著的区别。下面是它们的主要区别点&#xff1a; 1. 事务支持 InnoDB&#xff1a; 支持事务&#xff08;ACID 特性&#xff09;&#xff0c;即原子性、一致性、隔离性和持久性。支持行级…

pytorch笔记:named_parameters

named_parameters 是 PyTorch 中一个非常有用的函数&#xff0c;用于访问模型中所有定义的参数及其对应的名称。它是 torch.nn.Module 类的方法之一&#xff0c;返回一个生成器&#xff0c;生成 (name, parameter) 对&#xff0c;name 是参数的名称&#xff0c;parameter 是对应…

ZLMediakit交叉编译

ZLMediakit交叉编译 1 下载源码 #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit #千万不要忘记执行这句命令 git submodule update --init2 当前目录下建立 toolchain.cmake SET(CMAKE_SYSTEM_NAME Linux)…

【OpenCV 图像处理 Python版】图像处理的基本操作

文章目录 1.图像的 IO 操作1.1 图像读取 imread1.2 图像显示1.2.1 opencv 方式1.2.2 matplotlib 方式 1.3 图像保存 imwrite 2.绘制几何图形1. 绘制直线2. 绘制矩形3. 绘制圆形4. 绘制多边形5. 添加文字 3.获取并修改图像中的像素点3.1 获取像素值3.2 修改像素值3.3 获取和修改…

【python入门】字符串处理

文章目录 基本操作进阶操作 基本操作 Python 提供了多种方式来处理字符和字符串&#xff0c;以下是一些基本的字符处理方法&#xff0c;以及相应的代码示例&#xff1a; 字符串连接 ( 操作符或 join() 方法) # 使用 操作符连接字符串 str1 "Hello" str2 "Wo…

零基础想学编程,选择哪一门语言更好就业?(非常详细)零基础入门到精通,收藏这一篇就够了_c#就业方向

编程语言的用途广泛&#xff0c;它们各自在不同的领域和应用场景中发挥着重要作用。 零基础初学者在选择编程语言时&#xff0c;可以从就业方向入手选择。 【一一帮助安全学习&#xff0c;所有资源获取处一一】 ①网络安全学习路线 ②20份渗透测试电子书 ③安全攻防357页笔记 …

Maven高级理解属性

属性 在这一章节内容中&#xff0c;我们将学习两个内容&#xff0c;分别是 属性版本管理 属性中会继续解决分模块开发项目存在的问题&#xff0c;版本管理主要是认识下当前主流的版本定义方式。 4.1 属性 4.1.1 问题分析 讲解内容之前&#xff0c;我们还是先来分析问题: …

pdf压缩,pdf压缩在线,pdf压缩在线网页版

当我们遇到PDF文件过大&#xff0c;需要压缩其容量大小时&#xff0c;通常是为了更方便地传输、存储或分享这些文件。PDF文件的大小可能因其包含的图像、字体等元素的数量和质量而有所不同。下面&#xff0c;我们将详细介绍压缩PDF容量大小的方法&#xff0c;帮助您轻松实现文件…

《计算机网络自顶向下方法-第八版》

计算机网络自顶向下方法 IO多路复用技术epoll select poll的区别Reactor模式和Proactor模式&#xff0c;阻塞非阻塞&#xff0c;同步异步浏览器搜索过程电脑断网排查TCP/IP五层网络模型网络协议Http & HttpsHTTP状态码HTTP 常见字段GET 和 POSTHTTP1.1HTTP 与 HTTPS对称加密…

Vite打包速度为什么比webpack快,打包的优劣势在哪里?

大家都有被webpack打包速度搞崩溃的时候&#xff0c;修改一处地方&#xff0c;想预览效果&#xff0c;要等上半天。 Vite比Webpack快的原因 ESM&#xff08;ES Module&#xff09;原生支持&#xff1a; Vite基于ESM构建&#xff0c;利用浏览器原生支持的ESM模块加载方式&…

基于 JuiceFS 构建高校 AI 存储方案:高并发、系统稳定、运维简单

中山大学的 iSEE 实验室&#xff08;Intelligence Science and System) Lab&#xff09;在进行深度学习任务时&#xff0c;需要处理大量小文件读取。在高并发读写场景下&#xff0c;原先使用的 NFS 性能较低&#xff0c;常在高峰期导致数据节点卡死。此外&#xff0c;NFS 系统的…

【PL理论深化】(7) Ocaml 语言:静态类型语言 | 自动类型推断 | 多态类型和多态函数 | let-多态类型系统

&#x1f4ac; 写在前面&#xff1a;OCaml 是一种拥有静态类型系统的语言&#xff0c;本章我们就要探讨静态类型系统。 目录 0x00 静态类型系统 0x01 自动类型推断&#xff08;automatic type inference&#xff09; 0x02 多态类型和多态函数 0x03 let-多态类型系统&#…

kaggle数据集下载

目录 1. kaggle注册2. 解决下载慢的问题 1. kaggle注册 注册的时候出现验证码无法显示的问题&#xff0c;参考&#xff1a;https://blog.csdn.net/qq_41835735/article/details/131413062 2. 解决下载慢的问题 参考&#xff1a; https://blog.csdn.net/TracelessLe/article/…

暴雨虐长沙,生灵受煎熬

今天&#xff0c;“湖南长沙市遭遇强降雨,一小时的降雨量足够注满54个西湖”这消息&#xff0c;终于登上互联网社交平台热搜榜。 截图&#xff1a;来源社交网站 综合多家媒体消息概述如下。 昨&#xff08;24日&#xff09;天&#xff0c;湖南长沙市遭遇强降雨&#xff0c;一…

AI赋能影视解说:Rap说唱玩法拆解!

在影视解说的领域&#xff0c;竞争一直非常激烈&#xff0c;众多创作者纷纷涌入这个热门的赛道。为了在众多声音中脱颖而出&#xff0c;创新成为了关键。最近&#xff0c;一种结合AI技术的解说方式——Rap说唱解说&#xff0c;以其新颖的形式和高效的创作过程&#xff0c;赢得了…

kingbase R3修改pcp_watchdog密码

需要修改的文件 kingbasecluster/etc/HAmodule.conf kingbasecluster/etc/pcp.conf db/etc/HAmodule.conf 3个文件 两个节点都要改。 1.pcp.conf文件 cd kingbasecluster/bin ./sys_md5 12345678ab! 将结果复制拷贝到…/etc/pcp.conf中 放到kingbase:后面 也就是把kingbase 的密…

全面解决企业精准获客(AI+商机获客)

AI获客系统为电销企业带来了革命性的变化&#xff0c;特别是在精准获客方面。以下是如何全面帮助电销企业精准获客的一些关键点&#xff1a; 1. 大数据分析 - 系统能够收集和分析海量的客户数据&#xff0c;包括消费行为、兴趣爱好、在线活动等。 - 通过深度学习和机器学习算法…

Java面试八股之JVM内存溢出的原因及解决方案

JVM内存溢出的原因及解决方案 JVM内存溢出&#xff08;Out Of Memory&#xff0c;OOM&#xff09;通常是由于程序运行过程中内存使用不当造成的&#xff0c;常见原因及相应的解决方案如下&#xff1a; 原因及解决方案 内存中加载的数据量过大 原因&#xff1a;一次性从数据…

展厅设计中需要人性化的地方

1、预留参观空间 展厅空间的布局设计必须尽可能的宽敞&#xff0c;以避免参观人数较多时可能会发生的拥堵&#xff0c;重点展品需要预留较大的展示空间或四面通畅的中心位置&#xff0c;更方便观众从不同角度与方位参观。因为是展厅&#xff0c;不仅代表着企业形象&#xff0c;…

SolidWorks北京正版代理商亿达四方:官方授权SolidWorks中国代理

在北京这座融合了古老文明与现代科技的都市中&#xff0c;亿达四方作为SolidWorks官方认证的北京区域正版代理商&#xff0c;正引领着一场设计与制造领域的革新风潮。我们致力于为北京及周边地区的企业提供原汁原味的SolidWorks软件及全方位的增值服务&#xff0c;共同推进首都…