学习方法与心得
题目解析
问题描述
题目要求根据参与抢红包的金额对多个人进行排序。如果金额相同,则按参与抢红包的顺序进行排名。具体来说:
- 抢到金额越多的人排名越前;
- 若两人抢到的金额相同,则根据他们抢红包的顺序决定排名,先抢的排前面。
解题思路
1. 数据存储
- 我们需要保存每个人的名字和抢到的金额。可以将名字和金额一起存储在一个列表中,使用
Map.Entry<String, Integer>来记录每个人的名字和金额。
2. 排序规则
- 排序时,首先根据抢到的金额进行降序排序;
- 如果金额相同,则根据原始顺序(即数组中的顺序)进行排序。
3. 排序操作
- 使用
List.sort方法对数据进行排序,排序时:- 使用
b.getValue().compareTo(a.getValue())来确保金额从大到小排列; - 如果金额相同,通过比较原始顺序来保持先后次序。
- 使用
4. 提取结果
- 排序完成后,提取排序后的参与者名字,作为最终的结果返回。
代码实现
import java.util.*;
public class Main {
public static List<String> solution(int n, List<String> s, List<Integer> x) {
// 创建一个列表来存储参与者的信息
List<Map.Entry<String, Integer>> participants = new ArrayList<>();
// 将参与者的名字和抢到的金额存储到列表中
for (int i = 0; i < n; i++) {
participants.add(new AbstractMap.SimpleEntry<>(s.get(i), x.get(i)));
}
// 根据题目要求进行排序
participants.sort((a, b) -> {
// 首先按照金额降序排序
int cmp = b.getValue().compareTo(a.getValue());
// 如果金额相同,按照抢红包的顺序排序
if (cmp == 0) {
return s.indexOf(a.getKey()) - s.indexOf(b.getKey());
}
return cmp;
});
// 提取参与者的名字并返回
List<String> result = new ArrayList<>();
for (Map.Entry<String, Integer> entry : participants) {
result.add(entry.getKey());
}
return result;
}
public static void main(String[] args) {
// 测试用例
System.out.println(solution(4, Arrays.asList("a", "b", "c", "d"), Arrays.asList(1, 2, 2, 1)).equals(Arrays.asList("b", "c", "a", "d")));
System.out.println(solution(3, Arrays.asList("x", "y", "z"), Arrays.asList(100, 200, 200)).equals(Arrays.asList("y", "z", "x")));
System.out.println(solution(5, Arrays.asList("m", "n", "o", "p", "q"), Arrays.asList(50, 50, 30, 30, 20)).equals(Arrays.asList("m", "n", "o", "p", "q")));
}
}
核心算法分析
1. 时间复杂度
- 遍历参与者的列表需要 O(n),其中
n为参与者人数。 - 排序操作的时间复杂度为 O(n log n)。
- 因此,整个算法的时间复杂度是 O(n log n),其中
n为参与者人数。
2. 空间复杂度
- 我们使用了一个列表来存储参与者的名字和抢到的金额,空间复杂度是 O(n)。
3. 排序细节
- 使用
Comparator来对参与者进行排序,首先按照金额排序,其次根据顺序排序。 - 这种排序方式保证了题目中要求的“金额相同按顺序排”的规则。
知识总结
通过这道题目,我总结了以下几个重要知识点:
1. 如何使用 Map.Entry 存储一对数据
- 使用
Map.Entry来存储一对数据(如名字和金额)是很常见的方式,适用于需要同时记录两个相关数据的场景。
2. Comparator 的应用
- 排序是常见的操作,在这道题中,使用
Comparator通过自定义排序规则来实现排序,保证了金额相同的情况下,按照原始顺序排序。
3. 排序与时间复杂度
- 排序算法的时间复杂度通常是 O(n log n),是处理大量数据时的常见瓶颈。在面对更大规模的数据时,需要注意性能优化。
4. List 和 ArrayList 的使用
- 使用
ArrayList存储和操作动态数据。其索引访问速度为 O(1),非常适合用于这种排序、查找等频繁操作的场景。
学习计划
1. 强化排序算法的理解
- 学习并理解不同的排序算法,如快排、归并排序、堆排序等,了解它们的时间复杂度和适用场景。
2. 学习如何使用 Comparator
- 深入理解
Comparator的使用,掌握如何通过自定义排序规则来对数据进行灵活的排序。
3. 编写更多与数据结构相关的题目
- 针对列表、集合、映射等数据结构进行更多的实践,尤其是在实际问题中如何高效地存储和排序数据。
工具运用
1. 豆包MarsCode AI解析功能
- 利用 AI 提供的题目解析功能,快速理解题目中的难点与技巧,节省时间。
2. 调试与优化
- 在处理数据量较大的问题时,学习如何通过分析时间复杂度、空间复杂度来优化程序,尤其是在排序等操作中。
3. 代码重构与改进
- 学习如何根据题目的不同要求,灵活地调整数据结构和算法设计,提升代码的可读性和效率。
学习建议
- 先理解题目,再写代码
- 在动手写代码前,花时间理解题目的要求和细节,确保自己明白每个步骤的目的。
- 熟练掌握排序与比较
- 排序和比较是大部分算法题的基础,多做一些排序相关的题目,掌握如何使用不同的比较器。
- 思考时间和空间复杂度
- 在解决问题时,要时刻考虑时间复杂度和空间复杂度,尤其是在面对大规模数据时。通过优化算法,使代码更加高效。
通过这道题目,希望大家能够更加熟练地掌握排序操作,以及如何利用 Comparator 自定义排序规则,提升自己的编程能力!