题目背景
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他根据特定的规则来选择目标分数:如果分数中有三个或以上不同的分数,返回其中第三大的分数;如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。
题目要求
这个问题的核心在于对给定分数数组的处理和排序,以及如何根据数组中不同分数的数量来选择目标分数。
- 输入:n(数组长度),nums(分数数组)
- 输出:目标分数
思路解析
-
去重:首先,我们需要将分数数组中的重复分数去除,以便后续处理。
-
排序:将去重后的分数进行降序排序,这样我们可以方便地获取到最大的几个分数。
-
判断并返回:根据题目要求,判断不同分数的数量。如果数量大于等于3,则返回第三大的分数;如果数量小于3,则返回最大的分数。
根据上述步骤解决每个测试样例,如下:
样例1:
- 输入:
n = 3, nums = [3, 2, 1] - 步骤1:对数组进行降序排序:
[3, 2, 1] - 步骤2:计算不同分数的数量:3(3, 2, 1)
- 步骤3:选择第三大的分数作为目标:1
样例2:
- 输入:
n = 2, nums = [1, 2] - 步骤1:对数组进行降序排序:
[2, 1] - 步骤2:计算不同分数的数量:2(2, 1)
- 步骤3:选择最大的分数作为目标:2
样例3:
- 输入:
n = 4, nums = [2, 2, 3, 1] - 步骤1:对数组进行降序排序:
[3, 2, 2, 1] - 步骤2:计算不同分数的数量:3(3, 2, 1)
- 步骤3:选择第三大的分数作为目标:1
图解
- 假设输入为 n = 4, nums = [2, 2, 3, 1]
- 去重后得到 [1, 2, 3]
- 排序后得到 [3, 2, 1]
- 因为不同分数的数量大于等于3,所以返回第三大的分数 1
知识总结
-
集合(Set) :用于去重,自动移除列表中的重复元素。
set(nums):去除数组中的重复元素。 -
排序函数:
sorted()函数可以对任何可迭代对象进行排序,reverse=True参数使其降序排序。sorted(..., reverse=True):对去重后的数组进行降序排序。
针对以上问题,我们还可以通过使用堆(Heap)、快速选择算法(QuickSelect)、计数排序(Counting Sort)来解决。
堆是一种特殊的树形数据结构,其中每个父节点的值都大于或等于(大顶堆)或小于或等于(小顶堆)其子节点的值。
在这个问题中,我们可以使用大顶堆来找到第三大的分数。
- 构建大顶堆:在大顶堆中,最大的元素位于堆的顶部(即数组的第一个位置)。其中数组的第 i 个位置的元素是堆中第 i 个节点的值。
- 提取堆顶元素:由于需要找到第三大的分数,可以从大顶堆中提取(移除)堆顶元素两次,这样堆顶就剩下第三大的元素了。每次提取堆顶元素后,需要进行堆的调整(heapify),以确保堆的性质得以维持。
- 堆的调整(heapify):移除堆顶元素后,将堆的最后一个元素移动到堆顶,然后进行向下调整(shiftDown),以确保新的堆顶元素是当前子树中最大的元素。