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

92 阅读5分钟

问题背景

在多人在线游戏中,玩家们通过参与不同的比赛局次进行互动,团队协作和玩家之间的配合往往决定着游戏的胜负。在一些游戏中,系统会记录玩家的比赛历史,通过这些历史记录可以分析玩家之间的合作情况。题目要求根据历史记录来判定玩家是否为队友。特别地,若两名玩家至少一起参与过两局比赛,那么这两名玩家可以被认为是队友。

问题分析

在本问题中,我们有以下输入:

  1. id: 指定玩家的ID,目标是找到与这名玩家有过多次合作的其他玩家。
  2. num: 游戏历史记录的数量,虽然这个参数并未直接在题目中使用,但它给我们一个提示,即可能需要考虑历史记录表的大小。
  3. array: 记录了所有玩家的游戏参与信息,每个记录由两部分组成:玩家ID和游戏ID,表示某个玩家在某场游戏中的参与情况。

我们需要根据这些历史记录确定哪些玩家至少与指定玩家一起参与了两局比赛。如果符合条件,返回这些玩家的ID。

思路与步骤

  1. 数据结构选择:首先,我们需要一个有效的数据结构来存储玩家和其参与过的比赛。使用字典(player_games)是一个很好的选择,键是玩家的ID,值是该玩家参与过的所有游戏的集合(set)。使用集合的好处是,可以方便地进行交集运算,以判断两个玩家是否一起参与过同一场比赛。

  2. 数据处理

    • 首先,遍历比赛记录,将每个玩家和其对应的比赛ID存储到字典中。字典的值是一个集合,这样可以避免同一玩家在同一局比赛中重复记录。
    • 接着,获取指定玩家(id)参与过的所有比赛ID。
    • 对于其他每个玩家,计算该玩家与指定玩家的交集(即共同参与过的比赛数)。如果交集的大小大于等于2,则认为这两位玩家是队友。
  3. 排序与输出

    • 结果中的队友ID需要按升序排列,这就要求我们对结果列表进行排序。

代码实现

def solution(id, num, array):
    # 创建一个字典用于存储每个玩家参与的比赛
    player_games = {}
    
    # 遍历历史记录表,将玩家的比赛ID存入字典
    for record in array:
        player, game = record[0], record[1]
        if player not in player_games:
            player_games[player] = set()  # 使用集合存储玩家参与的比赛
        player_games[player].add(game)
    
    # 获取目标玩家的所有比赛ID
    target_games = player_games.get(id, set())
    
    # 初始化结果列表
    result = []
    
    # 遍历字典中的每个玩家,计算与目标玩家的共同比赛
    for player, games in player_games.items():
        if player == id:
            continue  # 跳过目标玩家本身
        count = len(games.intersection(target_games))  # 计算交集的大小
        if count >= 2:
            result.append(player)
    
    # 按升序排序结果列表
    result.sort()
    
    return result

if __name__ == "__main__":
    print(
        solution(
            1,
            10,
            [
                [1, 1],
                [1, 2],
                [1, 3],
                [2, 1],
                [2, 4],
                [3, 2],
                [4, 1],
                [4, 2],
                [5, 2],
                [5, 3],
            ],
        )
        == [4, 5]
    )

代码解析

  1. 创建字典

    player_games = {}
    

    我们使用一个字典 player_games 来存储每个玩家参与的游戏,字典的键是玩家ID,值是一个集合(set),集合中存储该玩家参加过的所有游戏ID。使用集合的好处是可以方便地判断玩家是否参与了相同的游戏。

  2. 遍历比赛记录

    for record in array:
        player, game = record[0], record[1]
        if player not in player_games:
            player_games[player] = set()
        player_games[player].add(game)
    

    遍历给定的比赛历史记录,将每一条记录的玩家ID和比赛ID添加到字典 player_games 中。如果玩家ID不存在,则初始化一个空集合,表示该玩家还没有参与任何游戏。

  3. 获取目标玩家的比赛ID集合

    target_games = player_games.get(id, set())
    

    通过字典的 get() 方法获取目标玩家 id 参与的比赛ID集合。如果目标玩家没有参与任何比赛,返回一个空集合。

  4. 计算队友

    for player, games in player_games.items():
        if player == id:
            continue
        count = len(games.intersection(target_games))
        if count >= 2:
            result.append(player)
    

    对字典中的每个玩家,计算他们与目标玩家共同参与的比赛数。我们通过集合的 intersection() 方法来获取两个玩家共同参与的游戏ID集合的大小,如果大于等于2,则认为这两名玩家是队友。

  5. 排序并返回结果

    result.sort()
    return result
    

    最后,对结果列表 result 进行升序排序,并返回该列表作为答案。

样例分析

样例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、2、3。
  • 玩家2参与了比赛1、4。
  • 玩家3参与了比赛2。
  • 玩家4参与了比赛1、2。
  • 玩家5参与了比赛2、3。

通过计算交集,玩家4和玩家5与玩家1有共同参与的比赛数都大于等于2,因此输出 [4, 5]

样例2

id = 2, num = 6, array = [[2, 1], [2, 3], [1, 1], [1, 2], [3, 1], [4, 3]]
  • 玩家2参与了比赛1、3。
  • 玩家1参与了比赛1、2。
  • 玩家3参与了比赛1。
  • 玩家4参与了比赛3。

没有玩家与玩家2共同参与两局及以上的比赛,因此输出 []

样例3

id = 3, num = 8, array = [[3, 1], [3, 2], [3, 3], [4, 1], [5, 2], [6, 3], [7, 1], [7, 2]]
  • 玩家3参与了比赛1、2、3。
  • 玩家4参与了比赛1。
  • 玩家5参与了比赛2。
  • 玩家6参与了比赛3。
  • 玩家7参与了比赛1、2。

玩家7与玩家3共同参与了比赛1和2,符合条件,因此输出 [7]

总结

本题考察了如何利用字典和集合来有效地管理和处理玩家的比赛历史记录,通过交集操作找出符合条件的队友。这个方法不仅清晰且高效,适用于类似的多人游戏数据分析问题。