返回
探索LeetCode 107:952- 按公因数计算最大组件大小
前端
2023-09-09 10:24:06
前言
踏入算法的奥妙世界,我们来到了LeetCode的第107站,迎接我们的是一道巧妙的图论问题——952- 按公因数计算最大组件大小。这道题的本质是寻找图中的连通分量,并找出其中最大的那个,而图中的节点和边是由给定数组的数字及其公因数所组成的。让我们踏上这段探索之旅,领略算法之美。
算法解析
连通分量
连通分量是指图中一组连通的节点,它们之间至少存在一条路径相连。找出最大连通分量就是找到连接最多的节点组。
公因数
题目要求我们以公因数作为边的依据构建图。对于给定的数组 nums,如果两个数字 i 和 j 存在公因数,那么我们就在图中添加一条从 i 到 j 的边。
算法步骤
- 初始化并查集: 创建并查集数据结构,它可以高效地管理节点的连通性。
- 遍历数组: 依次遍历数组 nums 中的每个数字 i。
- 分解质因数: 对于每个数字 i,分解其质因数,并将其存储在集合中。
- 遍历质因数: 对于 i 的每个质因数 p,查找集合中是否包含 p 的倍数。如果是,则使用并查集合并 i 和该倍数所在的连通分量。
- 统计最大连通分量: 在处理完所有数字后,遍历并查集,统计每个连通分量的节点数量。最大的连通分量就是我们需要的答案。
代码实现
from collections import defaultdict
def max_component_size(nums):
# 初始化并查集
parent = {n: n for n in nums}
rank = {n: 0 for n in nums}
# 遍历数组
for num in nums:
# 分解质因数
factors = set()
i = 2
while num > 1:
if num % i == 0:
factors.add(i)
while num % i == 0:
num //= i
i += 1
# 遍历质因数
for factor in factors:
# 查找集合中是否包含 factor 的倍数
p = factor
while p in parent:
p = parent[p]
# 合并连通分量
if p != num:
if rank[p] < rank[num]:
parent[p] = num
rank[num] += 1
else:
parent[num] = p
rank[p] += 1
# 统计最大连通分量
max_size = 0
for n in nums:
p = find_parent(n, parent)
max_size = max(max_size, rank[p])
return max_size
def find_parent(node, parent):
if parent[node] != node:
parent[node] = find_parent(parent[node], parent)
return parent[node]
复杂度分析
- 时间复杂度:O(n log n),其中 n 为数组 nums 的长度。
- 空间复杂度:O(n),存储并查集和质因数集合。
总结
这道题目融合了图论、并查集和质因数分解的知识,考察了算法设计和数据结构的应用能力。通过将数组中的数字及其公因数转化为图中的节点和边,我们巧妙地解决了寻找最大连通分量的难题。算法的实现清晰高效,展示了算法在实际问题中的应用。探索LeetCode的旅程仍在继续,让我们期待下一次的挑战和收获。