该题目的问题描述内容如下:
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下: 如果分数中有三个或以上不同的分数,返回其中第三大的分数。 如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。 请你帮小M根据给定的分数数组计算目标分数。
题目所给的输入输出样例为:
输入:
n = 3,nums = [3, 2, 1]输出:1
输入:n = 2,nums = [1, 2]输出:2
输入:n = 4,nums = [2, 2, 3, 1]输出:1
通过对题目进行简单的分析,不难看出这是一道与数组排序和去重相关的题目,目的是找到数组中第三大的分数,或者在特殊情况下返回最大分数。 要想求解该题,我们应该做到以下几点:
- 去除重复分数:需要处理重复分数,因为题目要求统计的是不同的分数。
- 排序操作:需要将分数从大到小排列以确定第三大的分数。
- 条件判断:根据不同分数的个数决定是返回第三大的分数还是最大分数。
第一眼看到该题时,我的思路大致为:
通过字典来统计每个分数的出现次数,然后根据字典中键的数量来判断是否存在三个或更多的不同分数。如果不同分数不足三个,直接返回最大的分数;否则,将字典的键(即去重后的分数集合)进行降序排序,取排序后的第三个元素作为结果。
具体代码如下:
def solution(n: int, nums: list) -> int:
score_hash = {}
for score in nums:
if score not in score_hash.keys():
score_hash[score] = 0
score_hash[score] += 1
if len(score_hash.keys()) < 3:
return max(score_hash.keys())
s = sorted(score_hash.keys(), reverse=True)
return s[2]
但仔细研究后,我们会发现这个思路有可以优化的地方:
我使用了字典 score_hash 来统计每个分数的出现次数,但实际上题目不需要统计频次,只需要去重后的分数集合。字典的额外信息没有被使用,因此可以用更简洁的方法实现。此外,代码的排序操作 sorted 每次都会遍历整个集合并排序,对于大规模输入的有潜在的性能风险。
于是,我们可以选择使用 set 去重,得到不同分数;而对于较大的数据集,我们还可以使用堆的方式维护一个大小为 3 的最小堆来记录前三大的分数,思路和代码如下:
- 使用最小堆存储最多 3 个不同的分数。
- 遍历数组,遇到新的分数时,根据堆的情况更新。
- 如果堆的大小达到 3,堆顶即为第三大的分数;否则返回堆中最大值。
import heapq
def solution(n: int, nums: list) -> int:
min_heap = []
unique_scores = set()
for num in nums:
if num not in unique_scores:
unique_scores.add(num)
heapq.heappush(min_heap, num)
if len(min_heap) > 3:
heapq.heappop(min_heap)
if len(min_heap) < 3:
return max(min_heap)
else:
return min_heap[0]