每日一题——Python实现PAT甲级1116 Come on! Let‘s C(举一反三+思想解读+逐步优化)五千字好文
一个认为一切根源都是“自己不够强”的INTJ
个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数
Python-3.12.0文档解读
目录
我的写法
代码点评
时间复杂度分析
空间复杂度分析
总结
我要更强
优化思路
优化后的代码
时间复杂度分析
空间复杂度分析
优化总结
哲学和编程思想
1. 时间复杂度与空间复杂度的权衡
哲学思想:资源优化(Resource Optimization)
2. 使用合适的数据结构
哲学思想:选择合适工具(Right Tool for the Job)
3. 减少不必要的操作
哲学思想:简洁性(Simplicity)
4. 一次性读取和输出数据
哲学思想:批处理(Batch Processing)
5. 高效的算法
哲学思想:算法优化(Algorithm Optimization)
6. 幂等性和状态管理
哲学思想:幂等性(Idempotency)与状态管理(State Management)
总结
举一反三
1. 优化时间和空间复杂度
技巧:
思想:
2. 使用合适的数据结构
技巧:
思想:
3. 减少不必要的操作
技巧:
思想:
4. 批处理和减少I/O操作
技巧:
思想:
5. 高效算法选择
技巧:
思想:
6. 幂等性和状态管理
技巧:
思想:
举一反三的应用
总结
题目链接
我的写法
import sys
import mathdef is_prime(num):if num <= 1:return Falseif num <= 3:return Trueif num % 2 == 0 or num % 3 == 0:return Falsefor i in range(5, int(math.sqrt(num)) + 1, 6):if num % i == 0 or num % (i + 2) == 0:return Falsereturn Trueinput = sys.stdin.read
data = input().split()
N = int(data[0])
ranklist_ids = {}
for i in range(1, N + 1):ranklist_ids[data[i]] = ichecked_ids = set()
K = int(data[N + 1])output = []for i in range(N + 2, K + N + 2):query_id = data[i]if query_id in ranklist_ids:if query_id in checked_ids:output.append(f"{query_id}: Checked")else:rank = ranklist_ids[query_id]if rank == 1:output.append(f"{query_id}: Mystery Award")elif is_prime(rank):output.append(f"{query_id}: Minion")else:output.append(f"{query_id}: Chocolate")checked_ids.add(query_id)else:output.append(f"{query_id}: Are you kidding?")# 将所有输出一次性打印,减少 I/O 操作
sys.stdout.write("\n".join(output) + "\n")
代码点评
这段代码实现了对一组ID的排名查询,并根据排名给出不同的反馈。代码结构清晰,使用了适当的数据结构(字典和集合)来优化查询效率。下面是对代码的详细点评:
- 模块导入:
- 使用了sys和math模块,分别用于处理输入输出和数学运算,这是合理的。
- 函数定义:
- is_prime函数用于判断一个数是否为素数,使用了优化的算法,只检查到平方根,减少了不必要的计算。
- 数据处理:
- 使用sys.stdin.read一次性读取所有输入,减少了I/O操作的次数。
- 将输入数据分割后存储在列表data中,方便后续处理。
- 数据结构使用:
- 使用字典ranklist_ids存储ID和其对应的排名,利用字典的快速查找特性,提高了查询效率。
- 使用集合checked_ids存储已检查的ID,避免了重复检查,优化了处理流程。
- 输出处理:
- 将所有输出存储在列表output中,最后一次性输出,减少了I/O操作的次数,提高了效率。
时间复杂度分析
- 读取输入:O(N + K),其中N是排名列表中的ID数量,K是查询的ID数量。
- 构建排名字典:O(N),遍历排名列表一次。
- 查询处理:O(K),每个查询操作的时间复杂度是O(1),因为使用了字典和集合。
- 输出:O(N + K),构建输出列表的时间。
总时间复杂度为O(N + K)。
空间复杂度分析
- 存储输入数据:O(N + K),需要存储所有输入数据。
- 排名字典:O(N),存储所有排名信息。
- 已检查ID集合:O(K),最多存储K个已检查的ID。
- 输出列表:O(K),存储所有查询结果。
总空间复杂度为O(N + K)。
总结
这段代码在处理大量数据时表现良好,时间复杂度和空间复杂度都与输入规模成线性关系,效率较高。代码结构清晰,使用了合适的数据结构和算法,是一段高质量的代码。
我要更强
这段代码已经相对高效,不过还是可以在一些细节上进行优化,以进一步提升性能。以下是一些可能的优化方法:
- 减少不必要的操作:在查询阶段直接读取和处理数据,而不是预先存储所有ID。
- 优化素数判断函数:虽然当前实现已经较优化,但我们可以进一步减少检查次数。
以下是经过优化的完整代码和分析:
优化思路
- 减少内存占用:只在需要时存储数据,而不是预先存储所有ID和排名。
- 优化素数判断:利用更高效的素数判断算法。
优化后的代码
python复制
import sys
import mathdef is_prime(num):"""判断一个数是否为素数"""if num <= 1:return Falseif num <= 3:return Trueif num % 2 == 0 or num % 3 == 0:return Falsefor i in range(5, int(math.sqrt(num)) + 1, 6):if num % i == 0 or num % (i + 2) == 0:return Falsereturn True# 从标准输入读取所有数据
input = sys.stdin.read
data = input().split()N = int(data[0]) # 排名列表中的ID数量
ranklist_ids = {data[i]: i for i in range(1, N + 1)} # 构建ID和排名的字典
checked_ids = set() # 存储已检查的ID
K = int(data[N + 1]) # 查询的ID数量output = [] # 用于存储最终输出的结果列表# 处理所有查询
for i in range(N + 2, N + 2 + K):query_id = data[i]if query_id in ranklist_ids:if query_id in checked_ids:output.append(f"{query_id}: Checked")else:rank = ranklist_ids[query_id]if rank == 1:output.append(f"{query_id}: Mystery Award")elif is_prime(rank):output.append(f"{query_id}: Minion")else:output.append(f"{query_id}: Chocolate")checked_ids.add(query_id)else:output.append(f"{query_id}: Are you kidding?")# 将所有输出结果一次性打印,减少I/O操作
sys.stdout.write("\n".join(output) + "\n")
时间复杂度分析
- 读取输入:O(N + K),其中N是排名列表中的ID数量,K是查询的ID数量。
- 构建排名字典:O(N),遍历排名列表一次。
- 查询处理:O(K),每个查询操作的时间复杂度是O(1),因为使用了字典和集合。
- 输出:O(K),构建输出列表的时间。
总时间复杂度为O(N + K)。
空间复杂度分析
- 存储输入数据:O(N + K),需要存储所有输入数据。
- 排名字典:O(N),存储所有排名信息。
- 已检查ID集合:O(K),最多存储K个已检查的ID。
- 输出列表:O(K),存储所有查询结果。
总空间复杂度为O(N + K)。
优化总结
通过以上优化,确保在时间和空间上的复杂度都保持在O(N + K)的水平,而代码的可读性和效率也得到了提升。这段优化后的代码更紧凑,并且在处理查询时更加直接。
哲学和编程思想
在优化这段代码的过程中,运用了多种编程思想和哲学,以提升代码的效率和可读性。以下是具体的分析:
1. 时间复杂度与空间复杂度的权衡
哲学思想:资源优化(Resource Optimization)
- 描述:在计算机科学中,时间和空间是两种重要的资源。通常情况下,优化一方面可能会牺牲另一方面,需要在两者之间找到一个平衡点。
- 应用:我们在优化过程中,确保时间复杂度和空间复杂度都保持在O(N + K)的水平,既保证处理速度,又不浪费内存资源。
2. 使用合适的数据结构
哲学思想:选择合适工具(Right Tool for the Job)
- 描述:不同的数据结构有不同的特点和适用场景,选择合适的数据结构能够显著提升程序的效率。
- 应用:使用了字典(
dict
)来存储ID与排名的映射,以实现快速查找操作(O(1)时间复杂度);使用集合(set
)来存储已检查的ID,以实现快速存在性检查(O(1)时间复杂度)。
3. 减少不必要的操作
哲学思想:简洁性(Simplicity)
- 描述:减少不必要的步骤和操作,使代码更加简洁高效。
- 应用:在查询阶段直接处理数据,而不是预先存储所有ID,这样减少了内存占用,并避免了多次遍历数据。
4. 一次性读取和输出数据
哲学思想:批处理(Batch Processing)
- 描述:通过一次性读取和处理大量数据,减少频繁I/O操作,提升程序运行效率。
- 应用:使用
sys.stdin.read
一次性读取所有输入数据,使用sys.stdout.write
一次性输出所有结果,减少了多次I/O操作的开销。
5. 高效的算法
哲学思想:算法优化(Algorithm Optimization)
- 描述:选择高效的算法来解决问题,减少计算量和时间开销。
- 应用:在素数判断中,使用优化的算法,仅检查到平方根且跳过明显非素数的数(如偶数和3的倍数),减少了不必要的计算。
6. 幂等性和状态管理
哲学思想:幂等性(Idempotency)与状态管理(State Management)
- 描述:在重复操作中确保操作结果不变,这样可以避免重复计算和不一致的结果。
- 应用:通过集合
checked_ids
记录已检查的ID,保证每个ID只处理一次,避免重复处理,确保程序状态一致性。
总结
通过运用以上哲学和编程思想,在优化过程中,既提升了代码的效率,又保持了代码的简洁和可维护性。这些思想不仅可以应用在这段代码中,对于其他编程任务同样适用,是编写高质量代码的重要原则。
举一反三
理解并应用编程哲学和思想能够大幅提升你的代码质量和效率。以下是一些常见的编程技巧和实践,每个技巧背后都有相关的哲学思想,希望能在不同的编程场景中灵活应用。
1. 优化时间和空间复杂度
技巧:
- 时间复杂度:在选择算法时,优先考虑时间复杂度较低的算法。例如,尽量避免使用O(n^2)的算法(如嵌套循环),可以考虑使用分治法、动态规划等优化算法。
- 空间复杂度:尽量减少不必要的数据存储,使用合适的数据结构(如数组、链表、哈希表)来优化内存使用。
思想:
- 资源优化:在开发过程中,始终考虑如何在时间和空间之间找到平衡点。
2. 使用合适的数据结构
技巧:
- 哈希表:用于快速查找、插入和删除操作。
- 数组/列表:用于需要快速访问元素的场景。
- 队列/栈:用于需要先进先出(FIFO)或后进先出(LIFO)操作的场景。
- 树/图:用于表示层次结构或连接关系的场景。
思想:
- 选择合适工具:根据具体问题选择最合适的数据结构,以提升程序的性能和可读性。
3. 减少不必要的操作
技巧:
- 懒加载:仅在需要时才初始化或计算数据,避免提前占用资源。
- 缓存:对于重复计算的结果进行缓存,避免多次计算相同的结果。
- 优雅的条件检查:尽量简化条件检查,避免多余的判断。
思想:
- 简洁性:代码应尽量简洁,减少不必要的复杂性。
4. 批处理和减少I/O操作
技巧:
- 批量读取和写入:尽量一次性读取或写入大量数据,减少I/O操作的次数。
- 缓冲区使用:使用缓冲区来提高I/O操作的效率。
思想:
- 批处理:通过一次性处理大量数据,提高程序的整体效率。
5. 高效算法选择
技巧:
- 分治法:将问题分解为规模较小的子问题再逐步解决,如快速排序、归并排序。
- 动态规划:通过记录中间结果,避免重复计算,如斐波那契数列、背包问题。
- 贪心算法:在每一步选择中做出局部最优选择,期望最终结果是全局最优,如最小生成树、活动选择问题。
思想:
- 算法优化:选择适合的高效算法解决问题,减少计算开销。
6. 幂等性和状态管理
技巧:
- 幂等操作:设计函数和方法时,确保对同一输入多次调用结果不变,常用于接口设计和数据库操作。
- 状态管理:使用状态管理工具(如Redux、Vuex)集中管理应用状态,避免不同部分状态不一致。
思想:
- 幂等性和状态管理:确保程序在重复操作中保持一致性,避免不必要的副作用。
举一反三的应用
-
优化查询操作:
- 思想:选择合适的数据结构(如哈希表)进行快速查找。
- 应用:在需要反复查找的场景中,优先使用哈希表来存储和查找数据。
-
减少重复计算:
- 思想:使用缓存(如Memoization)记录中间结果。
- 应用:在递归算法中,通过缓存已计算的结果,避免重复计算,提高效率。
-
简化代码逻辑:
- 思想:简化条件判断,减少嵌套层次。
- 应用:在复杂的条件判断中,尽量将相似的条件合并,或重构为多个简单函数,提高代码可读性。
-
批量操作:
- 思想:尽量一次性处理大量数据,减少I/O操作。
- 应用:在处理大文件或大量网络请求时,采用批量读取或写入的方式,减少I/O次数,提高效率。
总结
通过理解并应用这些编程技巧和思想,可以在不同的编程场景中灵活运用,提升代码的效率和可读性。每种技巧背后的思想都是编程中的基本原则,掌握这些原则将帮助在面对复杂问题时,能够更自如地找到最优解。
相关文章:

每日一题——Python实现PAT甲级1116 Come on! Let‘s C(举一反三+思想解读+逐步优化)五千字好文
一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码点评 时间复杂度分析 空间复杂度分析 总结 我要更强 优化思路 优化…...

spring-data-mongodb版本兼容问题
spring-data-mongodb与mongodb驱动有兼容性问题,不匹配会报NoSuchMethod异常,mongodb的java驱动包在4.0之后由mongodb-java-driver更名为mongodb-driver-sync。 spring-data-mongodb包依赖中有mongodb-driver-core,但缺诸如MongoCollection等…...

Java的核心类库
引言 在Java编程中,熟练掌握常用类与对象操作是开发的基础。Java的核心类库提供了丰富的功能,可以帮助开发者高效地处理各种编程任务。本文将详细介绍Java字符串操作、集合框架、日期与时间处理等内容,并通过图表和表格进行总结与示范。 字符…...

NSS题目练习9
[极客大挑战 2020]welcome 界面打开后一片空白,查看题目描述,翻译过来是 1.除了GET请求方法,还有一种常见的请求方法… 2.学习一些关于sha1和array的知识。 3.更仔细地检查phpinfo,你会发现标志在哪里。 补充: sh…...

JS 【算法】二分查找
使用场景 在有序数组中查找目标元素 const arr [1, 2, 3, 4, 5, 6, 7, 8, 9] const target 2 console.log(binarySearch1(arr, target)) console.log(binarySearch2(arr, target))循环实现 function binarySearch1(arr, target) {const length arr.lengthif (length 0) re…...

前端工程化工具系列(十四)—— Webpack(v5.91.0):应用模块打包器与构建工具
Webpack 是用于现代 JavaScript 应用程序的静态模块打包器。 当 webpack 处理应用程序时,它会在内部构建一个依赖关系图,该图映射项目所需的每个模块最终会生成一个或多个包。 1 概念 1.1 modules Webpack 中,无论是 JS 、CSS 还是图片等&…...

ThinkPHP+Bootstrap简约自适应网址导航网站源码
使用 ThinkPHPbootstrap 开发,后台采用全局 ajax 无刷新加载,前后台自适应,前台页面非常简洁适合自己收藏网站或做导航网站。 搭建教程: 1.整个主机 2.绑定解析域名 3.上传源码,解压 把解压出来的 nav.sql 文件导入数…...

Flutter 使用ffigen生成ffmpeg的dart接口
Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频 第六章 桌面端使用texture_rgba_renderer渲染视频 第七章 使用ff…...

(message): No CUDA toolset found.
解决方法: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\extras\visual_studio_integration\MSBuildExtensions\ 下的4个文件 复制到 D:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\BuildCustomizations\下。…...

【python】邮箱正则验证
当然可以。以下是一个使用Python正则表达式的例子,用于检查一个字符串是否是一个有效的电子邮件地址: import re def is_valid_email(email):regex r^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$return bool(re.match(regex, email)) # 测试电子邮件…...

深度学习(四)——torchvision中数据集的使用
1. 参数详解 torchvision中每个数据集的参数都是大同小异的,这里只介绍CIFAR10数据集 该数据集的数据格式为PIL格式 class torchvision.datasets.CIFAR10(root:str,train:boolTrue,transform:Optional[Callable]None,target_transform:Optional[Callable]None,do…...

【全开源】图书借阅管理系统源码(ThinkPHP+FastAdmin)
📚图书借阅管理系统:打造你的私人图书馆 一款基于ThinkPHPFastAdmin开发的简易图书借阅管理系统,一款轻量级的图书借阅管理系统,具有会员管理,图书管理,借阅及归还管理,会员充值等基本功能&…...

Mysql中使用where 1=1有什么问题吗
昨天偶然看见一篇文章,提到说如果在mysql查询语句中,使用where 11会有性能问题?? 这着实把我吸引了,因为我项目中就有不少同事,包括我自己也有这样写的。为了不给其他人挖坑,赶紧学习一下&…...

中心极限定理的MATLAB例
独立同分布的中心极限定理: 设 X 1 , X 2 , … , X n X_1, X_2, \ldots, X_n X1,X2,…,Xn 是独立同分布的随机变量序列,且 E ( X i ) μ E(X_i) \mu E(Xi)μ, D ( X i ) σ 2 > 0 D(X_i) \sigma^2 > 0 D(Xi)σ2>0&a…...

定义input_password函数,提示用户输入密码.如果用户输入长度<8,抛出异常,如果用户输入长度>=8,返回输入的密码
def input_password(password):str1passwordlen1len(str1)try:if len1<8:raise ValueError("密码长度不能小于8")else:return print(f"你的密码为:{password},请确认")except ValueError as e:print(f":Error is {e}")number1input("请…...

【深度学习】IP-Adapter 和 InstantID 的核心机制比较
IP-Adapter 和 InstantID 是两个在图像生成中具有不同优势和应用场景的模型。以下是这两个模型的区别及其理论分析。 IP-Adapter 特点: 图像提示能力: IP-Adapter 通过引入图像提示能力,使得预训练的文本到图像扩散模型可以接受图像作为提示,从而生成…...

JEPaaS 低代码平台 j_spring_security_check SQL注入漏洞复现
0x01 产品简介 JEPaaS是一款优秀的软件平台产品,可视化开发环境,低代码拖拽式配置开发,操作极其简单,可以帮助解决Java项目80%的重复工作,让开发更多关注业务逻辑,大大提高开发效率,能帮助公司大幅节省人力成本和时间成本,同时又不失灵活性。适用于搭建 OA、ERP、CRM、…...

天锐绿盾 | 无感知加密软件、透明加密系统、数据防泄漏软件
摘要:文件加密软件,包含禁止非授权的文件泄密和抄袭复制解决方案即使被复制泄密都是自动加密无法阅读,透明加密,反复制软件,内网监控,文件加密,网络安全方案,透明文件加密,加密文件,图纸加密,知识产权保护,加密数据; 通过绿盾信息安全管理软件,系统在不改…...

kubernetes(k8s)集群部署(2)
目录 k8s集群类型 k8s集群规划: 1.基础环境准备: (1)保证可以连接外网 (2)关闭禁用防火墙和selinux (3)同步阿里云服务器时间(达到集群之间时间同步) &…...

Git操作指南
1、提交代码操作 拉取线上分支,防止本地代码提交冲突 git pull origin dev git add . git commit -m “给本次提交添加注释” git push origin dev 2、打分支并切换分支 git checkout -b 新建并切换到新分支 切换到主分支 git checkout main git merge dev git p…...

全域推广和标准推广哪个更好。谁更容易获客?
随着全域概念的兴起,全域推广逐渐走进人们视野,并成为新的互联网热词。在此背景下,与全域推广相关的话题,如全域推广是什么及全域推广和标准推广的区别等成为了许多创业者讨论和搜索的对象。 所谓的全域推广,简单来说…...

首张地下地图!D-Wave 专用量子计算机助力沙特阿美完成地震成像
内容来源:量子前哨(ID:Qforepost) 文丨浪味仙 排版丨沛贤 深度好文:800字丨3分钟阅读 摘要:过去两年中,沙特阿美研究中心一直在使用总部在加拿大的D-Wave 公司的专用量子计算技术,…...

机器学习分类及算法
1. 深度学习 1.1学习算法 1.2基本术语和概念 1.3机器学习分类常用算法 1.3.1线性回归 1.3.2逻辑回归 1.3.3决策树 1.3.4朴素贝叶斯 1.3.5支持向量机SVM 1.3.6K-最近临邻KNN 还有K-均值(k-means)、随机森林、降维、人工神经网络等 1.4超参数和验证集 1.4.…...

电容器连接到 PCB 电源层的过孔配置
为什么我们需要去耦电容器? 时钟数字IC通常需要大的瞬态电源电流。例如,大型微处理器可以在很短的时间内消耗高达 10 A 的电流。随着 IC 输出的上升/下降时间缩短,我们需要以更高的速率提供瞬态能量。PCB 的电源和接地导体确实存在一定的电感…...

springboot+shiro+jwt 兼容session和token
最近和别的软件集成项目,需要提供给别人接口来进行数据传输,发现给他token后并不能访问我的接口,拿postman试了下还真是不行。检查代码发现项目的shiro配置是通过session会话来校验信息的 ,我之前一直是前后端自己写,用…...

CSS Display(显示)
CSS Display(显示) 概述 CSS(层叠样式表)中的display属性是控制元素如何显示的关键属性。它决定了元素的盒模型类型,即元素是块级元素、内联元素还是其他类型的元素。display属性对于网页布局和元素样式的控制至关重要。 基本用法 块级元…...

【PB案例学习笔记】-20制作一个超链接按钮
写在前面 这是PB案例学习笔记系列文章的第19篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...

Django中使用下拉列表过滤HTML表格数据
在Django中,你可以使用下拉列表(即选择框)来过滤HTML表格中的数据。这通常涉及两个主要步骤:创建过滤表单和处理过滤逻辑。 创建过滤表单 首先,你需要创建一个表单,用于接收用户选择的过滤条件。这个表单可…...

Linux基础 (十五):TCP 协议特点和UDP协议
上一节,我们学习了TCP协议的服务器-客户端的编程流程以及对中间的过程进行了详细的讨论,那么,这一节,我们对于TCP协议的特点进行进一步的分析,这也是面试的重点和难点。 目录 一、TCP 协议特点 1.1 连接的建立与断…...

python替换word文件中的图片
python替换word文件中的图片 模拟鼠标键盘,截屏 import glob import os import timeimport pyautogui import pyautogui as p from PIL import ImageGrab from pynput.keyboard import Controller# -*- coding:utf-8 -*-directory ./directory1 ./outputfor f i…...