问题描述
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下:
- 如果分数中有三个或以上不同的分数,返回其中第三大的分数。
- 如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。
请你帮小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
题目分析
题目要求我们找到给定分数数组中第三大的分数。具体规则如下:
- 如果分数中有三个或以上不同的分数,返回其中第三大的分数。
- 如果不同的分数只有两个或更少,那么返回最大的分数作为目标。
算法设计
为了实现这个功能,我们可以采用以下算法设计:
- 去重和排序:使用
TreeSet数据结构来去重并自动排序分数。 - 判断不同分数的数量:通过
TreeSet的大小判断不同的分数数量。 - 返回结果:根据判断结果返回相应的分数。
具体步骤
-
去重和排序:
- 创建一个
TreeSet对象。 - 遍历输入的分数数组,将每个分数添加到
TreeSet中。
- 创建一个
-
判断不同分数的数量:
- 检查
TreeSet的大小。 - 如果
TreeSet的大小小于3,说明不同的分数只有两个或更少。
- 检查
-
返回结果:
- 如果
TreeSet的大小小于3,返回TreeSet中的最大值(即最后一个元素)。 - 否则,返回
TreeSet中的倒数第三个元素。
- 如果
具体代码
`
import java.util.TreeSet;
public class Main {
public static int solution(int n, int[] nums) {
// 使用 TreeSet 来去重并排序
TreeSet<Integer> set = new TreeSet<>();
for (int num : nums) {
set.add(num);
}
// 判断去重后的分数数量
if (set.size() < 3) {
// 如果不同的分数只有两个或更少,返回最大的分数
return set.last();
} else {
// 否则,返回第三大的分数
// 由于 TreeSet 是升序排列的,我们需要取倒数第三个元素
Integer[] sortedArray = set.toArray(new Integer[0]);
return sortedArray[sortedArray.length - 3];
}
}
public static void main(String[] args) {
System.out.println(solution(3, new int[]{3, 2, 1}) == 1);
System.out.println(solution(2, new int[]{1, 2}) == 2);
System.out.println(solution(4, new int[]{2, 2, 3, 1}) == 1);
}
}`
关键步骤解释:
- TreeSet:
TreeSet是一个有序集合,它会自动对插入的元素进行排序并去重。 - 判断分数数量:通过
set.size()判断去重后的分数数量。 - 返回结果:如果分数数量小于3,直接返回最大的分数;否则,返回第三大的分数。
注意事项
-
数据结构选择:
- 使用
TreeSet可以自动去重并排序,但要注意TreeSet的插入和删除操作的时间复杂度为O(log n)。 - 如果数据量非常大,可以考虑其他数据结构或算法来优化性能。
- 使用
-
边界条件处理:
- 确保处理数组长度为0或1的特殊情况。
- 在实际应用中,可能需要对输入进行合法性检查,例如确保
n和nums的长度一致。
-
代码可读性:
- 使用有意义的变量名和注释,使代码更易于理解和维护。
- 将复杂的逻辑拆分成多个小函数,提高代码的可读性和可维护性。
-
性能优化:
- 如果
TreeSet的性能不满足需求,可以考虑使用其他数据结构,如PriorityQueue或手动维护一个大小为3的最大堆。 - 避免不必要的数组转换操作,直接在
TreeSet上进行操作。
- 如果