游戏队友搜索|豆包MarsCode AI刷题

105 阅读4分钟

游戏队友搜索|豆包MarsCode AI刷题

问题理解

题目要求我们根据玩家和比赛的历史记录,找到与指定玩家至少一起玩过两局比赛的所有玩家。这是一个典型的图论问题,可以通过构建图来解决。每个玩家可以看作图中的一个节点,如果两个玩家一起玩过比赛,则在它们之间建立一条边。我们需要找到与指定玩家有至少两条边的所有节点。

数据结构选择

  1. 图的表示

    • 使用 Map<Integer, Set<Integer>> 来表示图。键是玩家ID,值是一个集合,包含与该玩家一起玩过比赛的玩家ID。
  2. 比赛记录的存储

    • 使用 Map<Integer, Set<Integer>> 来存储每个玩家参与的比赛。键是玩家ID,值是一个集合,包含该玩家参与的所有比赛ID。

算法步骤

  1. 构建图

    • 遍历输入的比赛记录,填充 playerGames 和 playerGraph
  2. 统计共同比赛次数

    • 对于指定玩家,遍历其参与的所有比赛,找到其他玩家。
    • 统计每个其他玩家与指定玩家共同参与的比赛次数。
  3. 筛选结果

    • 筛选出共同参与比赛次数至少为2的玩家。

代码详解

import java.util.*;

public class Main {
    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(
                Arrays.equals(
                        solution(1, 10,
                                new int[][] {
                                        { 1, 1 }, { 1, 2 }, { 1, 3 }, { 2, 1 }, { 2, 4 }, { 3, 2 },
                                        { 4, 1 }, { 4, 2 }, { 5, 2 }, { 5, 3 }
                                }),
                        new int[] { 4, 5 }));
    }

    public static int[] solution(int id, int num, int[][] array) {
        // 创建一个Map来存储每个玩家参与的比赛
        Map<Integer, Set<Integer>> playerGames = new HashMap<>();
        
        // 遍历比赛记录,填充Map
        for (int[] record : array) {
            int player = record[0];
            int game = record[1];
            playerGames.putIfAbsent(player, new HashSet<>());
            playerGames.get(player).add(game);
        }
        
        // 获取指定玩家参与的比赛
        Set<Integer> targetGames = playerGames.getOrDefault(id, new HashSet<>());
        
        // 创建一个Map来存储其他玩家与指定玩家共同参与的比赛次数
        Map<Integer, Integer> commonGamesCount = new HashMap<>();
        
        // 遍历指定玩家参与的比赛,找到其他玩家
        for (int game : targetGames) {
            for (Map.Entry<Integer, Set<Integer>> entry : playerGames.entrySet()) {
                int otherPlayer = entry.getKey();
                if (otherPlayer == id) continue; // 跳过指定玩家
                Set<Integer> otherGames = entry.getValue();
                if (otherGames.contains(game)) {
                    commonGamesCount.put(otherPlayer, commonGamesCount.getOrDefault(otherPlayer, 0) + 1);
                }
            }
        }
        
        // 筛选出共同参与比赛次数至少为2的玩家
        List<Integer> resultList = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : commonGamesCount.entrySet()) {
            if (entry.getValue() >= 2) {
                resultList.add(entry.getKey());
            }
        }
        
        // 转换为数组并返回
        int[] result = new int[resultList.size()];
        for (int i = 0; i < resultList.size(); i++) {
            result[i] = resultList.get(i);
        }
        
        return result;
    }
}

知识点总结

  1. 数据结构

    • Map:用于存储键值对,适合存储玩家与比赛的关系。
    • Set:用于存储无序且不重复的元素,适合存储玩家参与的比赛ID。
  2. 算法

    • 遍历:通过遍历比赛记录,构建玩家与比赛的关系图。
    • 统计:通过遍历指定玩家参与的比赛,统计其他玩家与指定玩家共同参与的比赛次数。
    • 筛选:筛选出共同参与比赛次数至少为2的玩家。
  3. 图论

    • 通过构建图来表示玩家之间的关系,利用图的遍历和统计来解决问题。

学习建议

  1. 基础数据结构

    • 熟练掌握 Map 和 Set 的使用,理解它们的特点和适用场景。
  2. 算法思维

    • 培养通过数据结构和算法解决问题的思维方式,理解如何将实际问题转化为数据结构和算法问题。
  3. 图论基础

    • 学习图的基本概念和表示方法,理解如何通过图来解决实际问题。
  4. 代码实践

    • 多做练习,通过实际编写代码来加深对数据结构和算法的理解。
  5. 调试技巧

    • 学会使用调试工具,逐步分析代码的执行过程,找出问题所在。

个人理解

通过构建图来表示玩家之间的关系,利用图的遍历和统计来解决问题。通过选择合适的数据结构和算法,我们可以高效地解决这类问题。在实际编程中,理解问题的本质,选择合适的数据结构和算法,是解决问题的关键。

总结

通过问题的解析和代码实现,我们可以看到数据结构和算法在解决实际问题中的重要性。希望能通过不断的练习和学习,提升自己的编程能力。