原题链接:PTA | 程序设计类实验辅助教学平台
参考资料:【Python】 1038 统计同成绩学生 (20 分)_1038 统计同成绩学生 python-CSDN博客
Tips:以下Python代码仅个人理解,非最优算法,仅供参考!多学习其他大佬的AC代码!
原始代码在处理大数据集时效率较低的原因主要在于使用了
ls1.count(ls2[i])
来计算每个查询分数在ls1
中的出现次数。这个方法每次都会遍历整个
ls1
列表来查找ls2[i]
的出现次数,导致时间复杂度为 O(N*M),其中 N 是ls1
的长度,M 是ls2
中要查询的分数个数。当 N 和 M 都很大时,这个方法的效率会非常低。相比之下,算法使用字典(
score_count
)来存储ls1
中每个成绩的出现次数。这种方法只需要遍历ls1
一次(时间复杂度为 O(N)),然后对于每个查询分数,可以直接通过字典查找来得到其出现次数(平均时间复杂度为 O(1)),因此总的时间复杂度降低到 O(N + M)。字典在Python中是一种非常高效的数据结构,用于存储键值对,并支持快速的查找、插入和删除操作。在你的问题中,字典的键是学生的成绩,值是该成绩出现的次数。这种数据结构非常适合于解决这类“统计出现次数”的问题。
参考资料博主时间复杂度为:(O(n + k)),其中 n 是
score
列表的长度,k 是查询列表的长度只是我用的字典(考二级Python习惯用字典统计出现次数),复杂度一样的,变量名和存储数据容器不一样~
import sys
# 读取学生总人数N
N = int(sys.stdin.readline().strip())
# 读取N名学生的成绩,并统计每个成绩的出现次数
score_count = {}
for score in map(int, sys.stdin.readline().split()):
if score in score_count:
score_count[score] += 1
else:
score_count[score] = 1
# 读取要查询的分数,第一个K没用不必for取,直接in queries判断
queries = list(map(int, sys.stdin.readline().split()[1:]))
# 对每个查询分数,输出其对应的学生人数
results = [score_count.get(query, 0) for query in queries]
print(' '.join(map(str, results)))
# print(*results) #比上面join方法print慢15ms
'''以下代码测试点3超时,分数14 / 20
import sys
ls1,ls2,res = [],[],[]
N = int(sys.stdin.readline())
ls1 = list(map(int,sys.stdin.readline().split()))
ls2 = list(map(int,sys.stdin.readline().split()))
for i in range(1,ls2[0]+1):
res.append(ls1.count(ls2[i]))
print(*res)
'''