题目解析
这道题的目的是在一个多人游戏的环境下,通过比赛历史记录帮助指定玩家找到符合条件的队友。队友的定义是:如果两名玩家至少一起参加过两场比赛,则这两名玩家被视为队友。对于给定的玩家 ID,我们需要找出和他至少一起参加过两场比赛的其他玩家。
题目需求
我们有一个比赛记录表,每一条记录包含两个信息:
- 玩家 ID(表示该玩家的唯一标识)
- 比赛 ID(表示该玩家参与的某场比赛的标识)
我们需要根据这些记录来判断两名玩家是否符合“队友”关系。
输入和输出
-
输入:
id:指定玩家的 ID。num:比赛记录的数量。array:比赛记录的二维数组,其中每个元素为[玩家ID, 比赛ID]。
-
输出:
- 返回一个列表,包含符合条件的玩家 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 一起参加过两次或以上的比赛,因此输出为 []。
解题思路
为了找到指定玩家的队友,我们可以将解题过程分为几个步骤:
-
构建比赛记录映射:
- 遍历比赛记录,建立一个映射表
game_map,其中键为比赛 ID,值为该比赛中所有玩家的列表。 - 这样我们可以快速找到任意一场比赛中有哪些玩家参加。
- 遍历比赛记录,建立一个映射表
-
统计共同参与次数:
- 根据指定玩家的比赛历史,我们找到所有与之共同参加比赛的玩家,并统计他们的共同参与次数。
- 为此,我们需要一个字典
teammate_count,用于记录每个玩家与指定玩家的共同参与次数。
-
筛选符合条件的队友:
- 遍历
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_map和teammate_count。
总结
通过上述步骤,我们能够高效地找到指定玩家的符合条件的队友。