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

147 阅读4分钟

题目解析

这道题的目的是在一个多人游戏的环境下,通过比赛历史记录帮助指定玩家找到符合条件的队友。队友的定义是:如果两名玩家至少一起参加过两场比赛,则这两名玩家被视为队友。对于给定的玩家 ID,我们需要找出和他至少一起参加过两场比赛的其他玩家。

题目需求

我们有一个比赛记录表,每一条记录包含两个信息:

  • 玩家 ID(表示该玩家的唯一标识)
  • 比赛 ID(表示该玩家参与的某场比赛的标识)

我们需要根据这些记录来判断两名玩家是否符合“队友”关系。

输入和输出

  1. 输入

    • id:指定玩家的 ID。
    • num:比赛记录的数量。
    • array:比赛记录的二维数组,其中每个元素为 [玩家ID, 比赛ID]
  2. 输出

    • 返回一个列表,包含符合条件的玩家 ID,按升序排列。若没有符合条件的队友,返回空列表。

样例分析

我们可以通过具体的样例来进一步理解题目需求和解法:

样例 1

输入:id = 1, num = 10, array = [[1,1], [1,2], [1,3], [2,1], [2,4], [3,2], [4,1], [4,2], [5,2], [5,3]]

在这个样例中,玩家 1 的比赛历史是:

  • 比赛 1:玩家 1, 玩家 2, 玩家 4
  • 比赛 2:玩家 1, 玩家 3, 玩家 4, 玩家 5
  • 比赛 3:玩家 1, 玩家 5

从中可以看出,玩家 4 和玩家 5 都和玩家 1 共同参与了至少两场比赛。因此,符合条件的队友是 [4, 5]

样例 2

输入:id = 2, num = 6, array = [[2,1], [2,3], [1,1], [1,2], [3,1], [4,3]]

在这个样例中,玩家 2 的比赛历史是:

  • 比赛 1:玩家 2, 玩家 1, 玩家 3
  • 比赛 3:玩家 2, 玩家 4

没有玩家与玩家 2 一起参加过两次或以上的比赛,因此输出为 []

解题思路

为了找到指定玩家的队友,我们可以将解题过程分为几个步骤:

  1. 构建比赛记录映射

    • 遍历比赛记录,建立一个映射表 game_map,其中键为比赛 ID,值为该比赛中所有玩家的列表。
    • 这样我们可以快速找到任意一场比赛中有哪些玩家参加。
  2. 统计共同参与次数

    • 根据指定玩家的比赛历史,我们找到所有与之共同参加比赛的玩家,并统计他们的共同参与次数。
    • 为此,我们需要一个字典 teammate_count,用于记录每个玩家与指定玩家的共同参与次数。
  3. 筛选符合条件的队友

    • 遍历 teammate_count 字典,找出共同参与次数达到两次或以上的玩家,将他们加入结果列表,并按升序排序。

代码实现

以下是实现代码:

from collections import defaultdict

def find_teammates(id, num, array):
    # Step 1: 构建游戏ID到玩家列表的映射
    game_map = defaultdict(list)
    for player_id, game_id in array:
        game_map[game_id].append(player_id)
    
    # Step 2: 记录指定玩家与其他玩家共同参与的次数
    teammate_count = defaultdict(int)
    for game_id in game_map:
        if id in game_map[game_id]:
            # 统计与指定玩家共同参与比赛的玩家
            for player_id in game_map[game_id]:
                if player_id != id:
                    teammate_count[player_id] += 1
    
    # Step 3: 筛选出共同参与至少两次比赛的玩家
    teammates = [player_id for player_id, count in teammate_count.items() if count >= 2]
    
    return sorted(teammates)

# 测试样例
print(find_teammates(1, 10, [[1,1], [1,2], [1,3], [2,1], [2,4], [3,2], [4,1], [4,2], [5,2], [5,3]]))  # 输出:[4, 5]
print(find_teammates(2, 6, [[2,1], [2,3], [1,1], [1,2], [3,1], [4,3]]))  # 输出:[]
print(find_teammates(3, 8, [[3,1], [3,2], [3,3], [4,1], [5,2], [6,3], [7,1], [7,2]]))  # 输出:[7]

代码解释

Step 1:构建比赛记录映射表

我们使用 defaultdict(list) 来构建 game_map,将每场比赛的所有玩家分组存储。这样可以在后续操作中快速找到某场比赛的参与玩家。例如,对于样例 1 中的比赛记录,game_map 将构建如下映射:

{
  1: [1, 2, 4],
  2: [1, 3, 4, 5],
  3: [1, 5],
  4: [2]
}

Step 2:统计共同参与次数

通过遍历 game_map,我们找到指定玩家参加的比赛,并统计每个其他玩家与指定玩家共同参加的次数。例如,在样例 1 中,玩家 4 和 5 都分别与玩家 1 共同参加了两场比赛,因此 teammate_count 将包含:

{
  4: 2,
  5: 2
}

Step 3:筛选符合条件的队友

最后,我们遍历 teammate_count,筛选出共同参与次数大于或等于 2 的玩家,并将其结果按升序排列返回。

复杂度分析

  • 时间复杂度:(O(n)),其中 (n) 是比赛记录的数量,因为我们仅需遍历一次比赛记录来构建映射表,以及一次统计玩家共同参与次数。
  • 空间复杂度:(O(n)),用于存储 game_mapteammate_count

总结

通过上述步骤,我们能够高效地找到指定玩家的符合条件的队友。