题解:游戏排名第三大的分数
问题描述
小M 是一名热爱游戏的玩家,他希望通过查看往届游戏比赛的排名来确定自己的目标分数。他想找到往届比赛中排名第三的分数,作为自己的目标分数。具体规则如下:
- 如果分数中有三个或以上不同的分数,返回其中第三大的分数。
- 如果不同的分数只有两个或更少,返回最大的分数。
输入输出
- 输入:
- 整数
n表示分数的数量。 - 整数数组
nums表示分数列表。
- 整数
- 输出:
- 返回小M的目标分数。
示例
- 示例 1:
- 输入:
n = 3, nums = [3, 2, 1] - 输出:
1
- 输入:
- 示例 2:
- 输入:
n = 2, nums = [1, 2] - 输出:
2
- 输入:
- 示例 3:
- 输入:
n = 4, nums = [2, 2, 3, 1] - 输出:
1
- 输入:
解题思路
为了找到小M的目标分数,我们需要遵循以下步骤:
-
去重: 首先,我们需要使用集合(
set)来去掉分数列表中的重复分数,以获得唯一的分数列表。这样可以确保我们只处理不同的分数,避免重复计算。 -
排序: 接下来,我们将去重后的分数列表进行降序排序。排序后,第三大的分数就可以通过索引直接访问。
-
条件判断:
- 如果不同的分数数量大于等于3,我们返回第三大的分数(即索引为2的元素)。
- 如果不同的分数数量小于3,我们返回最大的分数(即索引为0的元素)。
通过这三个步骤,我们可以根据题目给定的规则找到小M的目标分数。
代码实现
以下是实现该逻辑的 Python 代码:
def solution(n: int, nums: list) -> int:
# 去重并转换为集合
unique_scores = set(nums)
# 将不同的分数排序
sorted_scores = sorted(unique_scores, reverse=True)
# 判断不同分数的数量
if len(sorted_scores) >= 3:
return sorted_scores[2] # 返回第三大的分数
else:
return sorted_scores[0] # 返回最大的分数
# 测试样例
if __name__ == '__main__':
print(solution(3, [3, 2, 1]) == 1) # 输出: True
print(solution(2, [1, 2]) == 2) # 输出: True
print(solution(4, [2, 2, 3, 1]) == 1) # 输出: True
复杂度分析
- 时间复杂度: O(n log n),主要是排序的时间复杂度。
- 空间复杂度: O(n),用于存储去重后的分数集合。
在时间复杂度方面,我们首先需要去重,这个过程的时间复杂度为 O(n)。然后,我们对去重后的分数列表进行排序,排序的时间复杂度为 O(n log n)。最后,我们只需要进行简单的条件判断,时间复杂度为 O(1)。因此,整个算法的时间复杂度为 O(n log n)。
在空间复杂度方面,我们需要使用一个集合来存储去重后的分数,因此空间复杂度为 O(n)。
总的来说,这个算法的时间复杂度和空间复杂度都是合理的,可以满足大多数的应用场景。通过这种方式,我们可以快速地找到小M的目标分数,为他的游戏目标提供参考。
以下为本题用到的知识
-
去重
- 在这个问题中,我们使用集合(
set)来去除分数列表中的重复元素。集合是一种无序、不重复的数据结构,非常适合用于去重的场景。
- 在这个问题中,我们使用集合(
-
排序
- 为了找到第三大的分数,我们需要对分数列表进行排序。这里使用了内置的
sorted()函数,它默认采用快速排序算法,时间复杂度为 O(n log n)。
- 为了找到第三大的分数,我们需要对分数列表进行排序。这里使用了内置的
-
条件判断
- 在找到第三大分数的过程中,我们需要根据分数列表的长度来判断返回结果。这里使用了
if-else语句来实现条件判断。
- 在找到第三大分数的过程中,我们需要根据分数列表的长度来判断返回结果。这里使用了
-
时间复杂度分析
- 去重的过程需要遍历一遍分数列表,时间复杂度为 O(n)。
- 排序的过程时间复杂度为 O(n log n)。
- 条件判断的过程时间复杂度为 O(1)。
- 因此,整个算法的时间复杂度为 O(n log n)。
-
空间复杂度分析
- 我们使用了一个集合来存储去重后的分数列表,因此空间复杂度为 O(n)。
总的来说,这个问题的解决方案利用了 Python 中集合和排序的相关知识,通过三个步骤(去重、排序、条件判断)来找到第三大的分数。时间复杂度为 O(n log n),空间复杂度为 O(n),满足大多数应用场景的需求。