学习笔记:从比赛分数中确定目标分数
学习心得与体会
通过这个问题的分析和解答,我认识到编程的核心是逻辑推导和问题拆解能力。尤其在面对复杂的规则时,分解问题、识别模式并运用适合的数据结构和算法可以大大简化解题过程。同时,考虑到边界条件和异常输入是编程中不可忽略的重要环节。
问题描述
目标:
帮助小M确定比赛的目标分数。
规则:
- 如果分数数组中有至少三个不同的分数,则返回第三大的分数。
- 如果只有两个或更少的不同分数,则返回最大的分数。
输入与输出:
- 输入:
n:表示数组长度。nums:包含比赛分数的整数数组。
- 输出:
- 满足条件的目标分数。
问题分析
主要难点
- 如何高效地找出数组中不同的分数?
- 如何根据不同分数的个数确定输出目标?
解题思路
- 去重与排序:
- 利用集合去除重复分数,从而获得不同分数的集合。
- 将集合转换为列表并按降序排列。
- 逻辑判断:
- 如果不同分数的个数≥3,返回第三大的分数。
- 否则,返回最大的分数。
边界条件
- 数组中所有分数都相同(如
[2, 2, 2])。 - 数组中只有一个分数(如
[1])。 - 数组为空。
代码实现
以下是基于 Python 的实现代码:
def find_target_score(n, nums):
# 去重并降序排序
unique_scores = sorted(set(nums), reverse=True)
# 判断不同分数的数量
if len(unique_scores) >= 3:
return unique_scores[2] # 第三大的分数
else:
return unique_scores[0] # 最大的分数
# 测试样例
print(find_target_score(3, [3, 2, 1])) # 输出: 1
print(find_target_score(2, [1, 2])) # 输出: 2
print(find_target_score(4, [2, 2, 3, 1])) # 输出: 1
测试样例分析
样例 1
- 输入:
n = 3, nums = [3, 2, 1] - 分析:
- 去重后分数为
[3, 2, 1]。 - 第三大的分数是
1。
- 去重后分数为
- 输出:
1
样例 2
- 输入:
n = 2, nums = [1, 2] - 分析:
- 去重后分数为
[2, 1]。 - 不同分数不足 3 个,选择最大的分数
2。
- 去重后分数为
- 输出:
2
样例 3
- 输入:
n = 4, nums = [2, 2, 3, 1] - 分析:
- 去重后分数为
[3, 2, 1]。 - 第三大的分数是
1。
- 去重后分数为
- 输出:
1
进一步优化
-
时间复杂度:
- 去重的时间复杂度为 (O(n))。
- 排序的时间复杂度为 (O(k \log k))((k) 为不同分数的个数)。
- 总体复杂度为 (O(n + k \log k)),已满足一般需求。
-
空间复杂度:
- 集合与排序占用的额外空间为 (O(k))。
-
改进方向:
- 如果数据量非常大且只关心第三大的分数,可以用最小堆优化,降低空间占用。
总结
通过本题的练习,我加深了对集合、排序等基础操作的理解,同时体会到程序结构的清晰性与鲁棒性的重要性。