问题描述
小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:抢到的金额越多,排名越靠前;如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小C和小U抢到的金额相同,但小C比小U先抢,则小C排在小U前面。
问题分解
具体来说,排名规则包括以下几点:
- 金额优先:抢到的总金额越多,排名越靠前。
- 顺序优先:如果两位参与者的总金额相同,则按照抢红包的先后顺序排名。
需求分析与设计
1. 需求分解
为了实现该排名系统,我们需要解决以下几个核心问题:
- 统计每个用户抢到的红包总金额。
- 在金额相同时,维护用户的抢红包顺序。
- 根据上述规则输出最终的排名列表。
2. 数据结构选择
为了解决这些问题,我们可以选择以下数据结构:
- 使用
Map<String, Integer>
来存储用户及其对应的红包总金额,其中键为用户名,值为金额。 - 使用
LinkedHashMap
保证插入顺序,这对于按抢红包顺序排名尤为重要。 - 通过
List
或Stream
实现排序逻辑。
3. 排序规则
排序的核心逻辑分为两步:
- 先比较金额大小,金额大的排在前面。
- 如果金额相同,则保持用户的插入顺序。
代码实现
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static List<String> solution(int n, List<String> s, List<Integer> x) {
// 使用 Map 统计每个用户的总金额
Map<String, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < s.size(); i++) {
map.put(s.get(i), map.getOrDefault(s.get(i), 0) + x.get(i));
}
// 根据金额降序排序,金额相同时按插入顺序排序(使用 LinkedHashMap 保证顺序)
return map.entrySet().stream()
.sorted((a, b) -> {
if (!b.getValue().equals(a.getValue())) {
return b.getValue() - a.getValue(); // 按金额降序
} else {
return 0; // 保持原顺序
}
})
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
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. 用户抢多个红包的处理
一个用户可能在活动中抢到多个红包,因此需要将其金额进行累加。为了实现这一点,可以在遍历用户数据时,通过 Map
的 getOrDefault
方法直接完成金额的累加逻辑。这里需要注意的是,如果使用的 Map
没有保证插入顺序(比如普通的 HashMap
),则排序结果可能会与期望不一致。
2. 数据排序的稳定性
在排序过程中,可能会涉及到金额相同的用户。为了解决金额相同时的顺序问题,选择 LinkedHashMap
是关键。该数据结构能够按照插入顺序保存用户数据,从而确保排名结果的稳定性。
3. 性能优化
在实际应用中,参与抢红包的用户可能达到成千上万,这对算法性能提出了较高要求。以下是优化点:
- 时间复杂度分析:用户数据的遍历为 (O(n)),排序为 (O(k *log k)),其中 (n) 是红包总数,(k) 是用户数。总体复杂度为 (O(n + k *log k))。
- 空间复杂度优化:利用流式操作减少中间结果的存储开销。
博客首页:总是学不会