豆包MarsCode AI刷题记录——学习方法与心得
问题描述
问题描述
在小C的班级里,有 N 个学生,每个学生的成绩是 A_i。小C发现了一件有趣的事:当且仅当某个学生的成绩小于或等于自己的有更多人时,这个学生会说谎。换句话说,如果分数小于等于他的学生数量大于比他分数高的学生数量,则他会说谎。
现在,小C想知道班里有多少个学生会说谎。
题目解析
这道题的理解可以从这几个方面来考虑:
- 排序:首先,对成绩数组进行排序。这样,对于每个学生,我们可以轻松地计算出有多少学生的成绩小于或等于他,以及有多少学生的成绩高于他。
- 计算小于等于和大于的数量:对于数组中的每个学生,我们可以通过遍历排序后的数组来计算有多少学生的成绩小于或等于他(包括他自己),以及有多少学生的成绩高于他。
- 判断说谎的学生:根据题目中的定义,如果一个学生的成绩小于或等于他的学生数量大于比他成绩高的学生数量,那么这个学生会说谎。在排序后的数组中,对于每个学生,我们可以通过计算他在数组中的位置来判断说谎的学生。具体来说,如果一个学生的位置 i 满足
i >= len(A) / 2,那么他的成绩小于或等于他的学生数量一定大于比他成绩高的学生数量。 - 计数:遍历数组,对于每个满足说谎条件的学生,计数器加一。
代码详解
def solution(A):
count = 0
for i in range(len(A)):
less_or_equal = sum(1 for j in range(len(A)) if A[j] <= A[i])
greater = len(A) - less_or_equal
if less_or_equal > greater:
count += 1
return count
if __name__ == "__main__":
print(solution([100, 100, 100]) == 3)
print(solution([2, 1, 3]) == 2)
print(solution([30, 1, 30, 30]) == 3)
print(solution([19, 27, 73, 55, 88]) == 3)
print(solution([19, 27, 73, 55, 88, 88, 2, 17, 22]) == 5)
知识点总结
1. 排序 (Sorting)
- 排序操作是解决这个问题的关键。通过对学生的成绩进行排序,我们可以更高效地计算每个学生的
less_or_equal和greater。 - 排序的时间复杂度是
O(N log N),这里使用的排序方法(如sorted())通常是基于 快速排序 或 归并排序,其平均时间复杂度为O(N log N)。
2. 二分查找 (Binary Search)
- 虽然在这段代码中我们没有显式使用二分查找,但通过排序后的数组,我们实际上可以用二分查找来快速计算
less_or_equal(小于等于当前元素的个数)。 - 在排序后的数组中,我们可以通过二分查找来定位当前元素
A[i]应该插入的位置,从而得知小于或等于它的元素数量。这个操作的时间复杂度是O(log N)。
3. 索引和数组操作 (Indexing and Array Manipulation)
- 索引查找是计算
less_or_equal的核心,sorted_A.index(A[i]) + 1计算了当前成绩在排序后的数组中的位置,从而知道有多少个元素小于或等于该成绩。 greater = N - less_or_equal计算出比当前成绩高的元素数量。这个操作利用了排序数组的特性。
4. 时间复杂度 (Time Complexity)
- 排序的时间复杂度是
O(N log N)。 - 查找每个元素的
less_or_equal和greater的时间复杂度是O(log N)(通过二分查找或者直接用索引)。遍历整个数组的时间复杂度是O(N)。 - 所以,整体的时间复杂度是 O(N log N) ,这是这个问题的最优复杂度,能够高效地处理较大的数据集。
5. 空间复杂度 (Space Complexity)
- 排序需要使用额外的空间来存储排序后的数组,因此空间复杂度是
O(N),这意味着我们需要额外的空间来存储排序后的成绩数组。
6. 条件判断 (Conditional Logic)
- 代码通过
if less_or_equal > greater:来判断每个学生是否会说谎。这个简单的条件判断是解决问题的核心逻辑部分。 - 判断每个学生成绩是否满足“成绩小于等于自己的人数大于比自己成绩高的人数”的条件。
7. 列表的操作 (List Operations)
- 使用
sorted()对成绩进行排序。sorted()是 Python 中用于排序的内置函数,返回一个新的排序后的列表。 - 使用
index()方法查找一个元素在列表中的位置。在排序后的数组中,index()可以帮助我们计算出当前成绩小于或等于自己的元素个数。
8. 算法设计的核心思想
- 问题拆解与优化: 初看问题可能需要遍历整个数组来比较每个学生的成绩,但通过排序和索引查找的技巧,我们将问题从暴力的
O(N^2)降低到O(N log N)。 - 空间与时间权衡: 虽然我们需要额外的空间来存储排序后的数组,但这换取了更快的计算速度,避免了重复计算和嵌套循环。
复杂度分析
- 时间复杂度:O(n^2),因为有一个嵌套循环,每个元素都需要与数组中的其他所有元素进行比较。
- 空间复杂度:O(1),因为除了输入数组外,只使用了固定数量的额外空间。
AI刷题体验
通过豆包 MarsCode 的 AI 刷题功能,我深刻感受到 AI 在教育中的巨大潜力。它不仅改变了我们学习的方式,更让我们重新审视学习的本质:学习是一个自我发现、自我提升的过程,而不仅仅是完成任务和获取成绩。