青训营X豆包MarsCode技术训练营 | 豆包MarsCode AI刷题04

99 阅读3分钟

问题描述

在一款多人游戏中,每局比赛需要多个玩家参与。如果发现两名玩家至少一起玩过两局比赛,则可以认为这两名玩家互为队友。现在你有一份玩家(通过玩家ID标识)和比赛局次(通过比赛ID标识)的历史记录表,目标是帮助某位指定玩家找到所有符合条件的队友。

例如,已知以下比赛历史记录:

| 玩家ID | 游戏ID

屏幕截图 2024-11-25 102715.png

问题分析

问题要求我们根据玩家的比赛历史记录,找出与指定玩家至少一起玩过两局比赛的所有玩家。我们可以通过以下步骤来解决这个问题:

  1. 数据结构选择

    • 使用HashMap来记录每个玩家与指定玩家一起比赛的次数。HashMap的键是玩家ID,值是该玩家与指定玩家一起比赛的次数。
  2. 遍历比赛记录

    • 对于每一条比赛记录,检查当前玩家是否是目标玩家。
    • 如果是目标玩家,则查找与目标玩家一起比赛的玩家,并增加他们在HashMap中的计数。
  3. 筛选队友

    • 遍历HashMap,找到所有与目标玩家一起比赛至少两局的玩家,并将他们添加到一个列表中。
  4. 返回结果

    • 将列表转换为数组并返回。

相关知识点解析

  1. HashMap

    • HashMap是Java中的一种数据结构,用于存储键值对。它提供了快速的查找、插入和删除操作。
    • 在本问题中,我们使用HashMap来记录每个玩家与指定玩家一起比赛的次数。键是玩家ID,值是比赛次数。
  2. 嵌套循环

    • 为了统计每个玩家与指定玩家一起比赛的次数,我们需要嵌套遍历比赛记录。外层循环遍历所有比赛记录,内层循环查找与目标玩家一起比赛的玩家。
  3. List和数组转换

    • List是Java中的一种动态数组,可以方便地添加和删除元素。
    • 在本问题中,我们使用List来存储符合条件的队友,最后将其转换为数组返回。
  4. Map.Entry

    • Map.EntryHashMap中键值对的接口。通过遍历Map.Entry,我们可以方便地访问HashMap中的键和值。

代码实现

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}));
        System.out.println(Arrays.equals(solution(2, 6, new int[][]{{2, 1}, {2, 3}, {1, 1}, {1, 2}, {3, 1}, {4, 3}}), new int[]{}));
        System.out.println(Arrays.equals(solution(3, 8, new int[][]{{3, 1}, {3, 2}, {3, 3}, {4, 1}, {5, 2}, {6, 3}, {7, 1}, {7, 2}}), new int[]{7}));
    }

    public static int[] solution(int id, int num, int[][] array) {
        // 使用HashMap来记录每个玩家与指定玩家一起比赛的次数
        Map<Integer, Integer> teammateCount = new HashMap<>();

        // 遍历比赛记录
        for (int[] record : array) {
            int playerId = record[0];
            int gameId = record[1];

            // 如果当前玩家是目标玩家
            if (playerId == id) {
                // 找到与目标玩家一起比赛的玩家
                for (int[] otherRecord : array) {
                    if (otherRecord[1] == gameId && otherRecord[0] != id) {
                        // 增加该玩家与目标玩家一起比赛的次数
                        teammateCount.put(otherRecord[0], teammateCount.getOrDefault(otherRecord[0], 0) + 1);
                    }
                }
            }
        }

        // 找到所有与目标玩家一起比赛至少两局的玩家
        List<Integer> teammates = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : teammateCount.entrySet()) {
            if (entry.getValue() >= 2) {
                teammates.add(entry.getKey());
            }
        }

        // 将结果转换为数组并返回
        int[] result = new int[teammates.size()];
        for (int i = 0; i < teammates.size(); i++) {
            result[i] = teammates.get(i);
        }

        return result;
    }
}

总结

通过使用HashMap来记录每个玩家与指定玩家一起比赛的次数,并结合嵌套循环和List与数组的转换,我们可以有效地解决这个问题。这种方法的时间复杂度为O(n^2),其中n是比赛记录的数量。虽然这种方法在比赛记录数量较大时可能效率不高,但对于小规模数据集是可行的。