问题描述
在小C的班级里,有个学生,每个学生的成绩是。小C发现了一件有趣的事:当且仅当某个学生的成绩小于或等于自己的有更多人时,这个学生会说谎。换句话说,如果分数小于等于他的学生数量大于比他分数高的学生数量,则他会说谎。
现在,小C想知道班里有多少个学生会说谎。
测试样例
样例1:
输入:
A = [100, 100, 100]
输出:3
样例2:
输入:
A = [2, 1, 3]
输出:2
样例3:
输入:
A = [30, 1, 30, 30]
输出:3
样例4:
输入:
A = [19, 27, 73, 55, 88]
输出:3
样例5:
输入:
A = [19, 27, 73, 55, 88, 88, 2, 17, 22]
输出:5
题目解析:
核心条件
- 假设分数为 ,小于等于该分数的学生数量为 ,比该分数高的学生数量为 。
- 总学生数为 ,则有: =−
- 当 >,即 >时,该学生会说谎。
思路分析:
-
成绩频率统计:
- 统计每个成绩出现的频率,构建一个频率表
freq。
- 统计每个成绩出现的频率,构建一个频率表
-
排序并计算前缀和:
- 对成绩进行排序,并依次计算小于等于当前成绩的学生数量(即前缀和)。
-
判断是否说谎:
- 对于每个成绩,检查
2*prefix_sum > N是否成立。 - 如果成立,则该成绩对应的所有学生都算说谎。
- 对于每个成绩,检查
-
累计结果:
- 将满足条件的学生数量累加,得到最终结果。
解决方案:
代码实现:
def solution(A):
# 手动统计频率
freq = {}
for score in A:
if score in freq:
freq[score] += 1
else:
freq[score] = 1
# 按成绩排序,计算前缀和
sorted_scores = sorted(freq.keys())
prefix_sum = 0 # 小于等于当前成绩的学生数量
liars = 0 # 说谎的学生数量
for score in sorted_scores:
prefix_sum += freq[score] # 累加当前成绩的学生数量
if 2 * prefix_sum > len(A):
liars += freq[score] # 当前成绩的所有学生都算说谎
return liars
代码解释:
-
统计频率:
- 构建成绩频率表
freq,统计每个成绩的出现次数。 - 输入
A=[100,100,100]时,结果为freq={100:3}。
- 构建成绩频率表
-
排序与前缀和:
- 将成绩按从低到高排序。
- 依次计算小于等于当前成绩的学生数量(前缀和)。
-
判断是否说谎:
- 对于每个成绩,检查前缀和是否满足
2*prefix_sum > N。 - 如果满足,当前成绩对应的所有学生都说谎。
- 对于每个成绩,检查前缀和是否满足
-
结果返回:
- 累计满足条件的学生数量。
示例测试:
-
样例1:
print(solution([100, 100, 100])) # 输出 3 -
样例2:
print(solution([2, 1, 3]))# 输出 2
时间复杂度:
时间复杂度
-
频率统计:遍历数组 A,时间复杂度为 。
-
成绩排序:对 freq.keys() 进行排序,时间复杂度为 ,其中 是不同分数的个数。
-
前缀和计算:遍历所有成绩,时间复杂度为 。
-
总复杂度:
空间复杂度:
-
频率表:需要存储成绩频率,空间复杂度为 。
-
总空间复杂度:
总结
通过频率统计和前缀和计算,能够高效判断每个分数下是否会说谎。
该算法的时间复杂度适中,适用于处理中等规模的成绩数据。