如何对ArrayList排序以实现元素多样性,避免同类元素聚集?
组队场景下满足多样性要求的列表排序实现
核心实现思路
排序的核心目标是打散相同姓氏的连续排布,保证后续顺序遍历分配队伍时,同姓氏参与者不会扎堆进入同一支队伍,从逻辑上匹配规则:只有所有已组建队伍都覆盖某姓氏成员时,后续同姓氏参与者才能被分配到已有该姓氏的队伍中。
具体操作步骤
- 第一步:对原始参与者列表按姓氏做分组统计
遍历传入的ArrayList<Participant>,以姓氏为键,把同姓氏的参与者存入对应的队列结构,同时统计每个姓氏的总人数。 - 第二步:按姓氏人数从高到低排序所有分组
将人数更多的姓氏分组排在前面处理,避免高频姓氏的参与者最后被集中堆到列表尾部。 - 第三步:按轮次穿插填充排序列表
循环从排序好的每个分组里取一个参与者依次放入结果列表,直到所有分组的参与者都被取完,最终得到打散排布的排序列表。
参考实现代码
ArrayList<Participant> list = tourney.getUnattatchedParticipants(); // 待实现的排序逻辑开始 // 按姓氏分组存储同姓氏参与者 Map<String, Queue<Participant>> surnameGroups = new HashMap<>(); for (Participant p : list) { surnameGroups.computeIfAbsent(p.getSurname(), k -> new LinkedList<>()).add(p); } // 按各姓氏的人数从多到少排序分组 List<Queue<Participant>> orderedGroups = new ArrayList<>(surnameGroups.values()); orderedGroups.sort((g1, g2) -> Integer.compare(g2.size(), g1.size())); // 轮次穿插构建排序列表 List<Participant> sortedList = new ArrayList<>(list.size()); int totalParticipants = list.size(); while (sortedList.size() < totalParticipants) { for (Queue<Participant> group : orderedGroups) { if (!group.isEmpty()) { sortedList.add(group.poll()); } } } // 替换原列表为排序后的结果 list.clear(); list.addAll(sortedList); // 待实现的排序逻辑结束
效果说明
这种排布方式会让同姓氏的参与者均匀分散在列表的不同位置,按顺序逐次分配队伍时:
- 前N个同姓氏的参与者(N等于总队伍数)会被依次分到每一支不同的队伍里
- 超出队伍数量的同姓氏参与者,自然会落在已经有该姓氏成员的队伍中,完全匹配题目给定的分配规则
注意:如果存在某姓氏的人数超过总队伍数的场景,该方案也不会出现同姓氏连续扎堆的问题,始终将队伍构成的多样性维持在最高水平。
内容的提问来源于stack exchange,提问作者Max Biggerstaff
相关产品推荐
相关产品推荐

