题目解析
本题的目的是为一个指定的玩家 id,找到在给定的比赛记录中,符合以下条件的队友:
-
队友条件:两名玩家一起参加过至少两局相同的比赛。
-
输入:
- ID:指定玩家的 ID。
- num:比赛历史中总的玩家数量。
- array:二维数组,每个元素是 (玩家ID, 游戏ID),表示某个玩家参与了一局比赛。
-
输出:返回一个列表,包含符合条件的队友的 ID,按照升序排列。如果没有队友,则返回空列表。
解题思路
我们可以分解问题为以下几个步骤:
1. 构建玩家-比赛映射关系
- 遍历输入的比赛历史记录 ( \text{array} ),为每个玩家建立其参加过的比赛集合。
- 例如,对于
array = [[1, 1], [1, 2], [2, 1], [3, 2]]
,得到:{ 1: {1, 2}, 2: {1}, 3: {2} }
2. 确定指定玩家的比赛集合
- 根据 ( \text{id} ),找到该玩家参加过的比赛集合 games_id。
- 例如,对于玩家 1,其比赛集合为
{1, 2}
。
3. 判断队友条件
- 遍历其他玩家的比赛集合,计算该玩家与 id 的比赛集合交集的大小:
- 如果交集大小<2,说明该玩家满足队友条件。
- 将符合条件的玩家 ID 记录下来。
4. 输出结果
- 将符合条件的队友的玩家 ID 按照升序排列返回。
图解
以示例 1 为例:
输入:
id = 1
array = [
[1, 1], [1, 2], [1, 3],
[2, 1], [2, 4], [3, 2],
[4, 1], [4, 2],
[5, 2], [5, 3]
]
Step 1: 构建玩家-比赛映射关系:
{
1: {1, 2, 3},
2: {1, 4},
3: {2},
4: {1, 2},
5: {2, 3}
}
Step 2: 找到玩家 1 的比赛集合:
games_id = {1, 2, 3}
Step 3: 遍历其他玩家,计算与玩家 1 的比赛集合交集大小:
- 玩家 2 的比赛集合:
{1, 4}
,交集{1}
,大小为 1,不满足条件。 - 玩家 3 的比赛集合:
{2}
,交集{2}
,大小为 1,不满足条件。 - 玩家 4 的比赛集合:
{1, 2}
,交集{1, 2}
,大小为 2,满足条件。 - 玩家 5 的比赛集合:
{2, 3}
,交集{2, 3}
,大小为 2,满足条件。
Step 4: 返回结果:
[4, 5]
Python 实现
以下是完整的代码:
def solution(id, num, array):
from collections import defaultdict
# Step 1: 构建玩家-比赛映射
player_games = defaultdict(set)
for player_id, game_id in array:
player_games[player_id].add(game_id)
# Step 2: 找到指定玩家的比赛集合
target_games = player_games[id]
if not target_games:
return []
# Step 3: 判断队友条件
teammates = []
for player_id, games in player_games.items():
if player_id == id:
continue # 跳过自己
# 计算交集大小
if len(target_games & games) >= 2:
teammates.append(player_id)
# Step 4: 返回结果(升序排序)
return sorted(teammates)
# 测试代码
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]
)
print(
solution(
2,
6,
[
[2, 1],
[2, 3],
[1, 1],
[1, 2],
[3, 1],
[4, 3],
],
)
== []
)
print(
solution(
3,
8,
[
[3, 1],
[3, 2],
[3, 3],
[4, 1],
[5, 2],
[6, 3],
[7, 1],
[7, 2],
],
)
== [7]
)
复杂度分析
-
时间复杂度:
- 构建玩家-比赛映射:O(n)O(n),其中 nn 是比赛记录的数量。
- 遍历玩家计算交集:对于每个玩家,计算交集的时间复杂度为 O(k)O(k),其中 kk 是玩家比赛集合的平均大小。总复杂度为 O(m⋅k)O(m⋅k),其中 mm 是玩家的总数量。
- 总时间复杂度为 O(n+m⋅k)O(n+m⋅k)。
-
空间复杂度:
- 存储玩家-比赛映射,空间复杂度为 O(n)O(n)。
知识点总结
- 集合操作:通过 Python 的集合交集操作
&
,可以高效计算两个集合的公共元素。 - 字典映射:使用
defaultdict
来构建映射关系,可以避免手动初始化字典值。 - 排序:在返回结果时,记得对结果列表排序以满足题目要求。
学习建议
- 刷题计划:
- 每天选择 3-5 道题目,逐步提升难度,从简单的查找问题到复杂的数据结构问题。
- 定期复盘错题,总结常见的错误和解题技巧。
- 利用 AI 辅助:
- 当遇到不理解的题目时,利用 AI 生成提示和思路,逐步掌握核心算法。
- 构建知识体系:
- 分类整理题目:例如,本题可以归类为“集合操作 + 哈希映射”。
- 针对薄弱环节,例如复杂度优化,多练习相关题目。