此题解采用了并查集的数据结构来处理名字的等价关系。首先,通过处理synonyms列表来构建一个等价关系图,将具有相同含义的名字进行合并。合并规则是,总是让字典序较小的名字作为代表。接着,通过遍历names列表,将每个名字的频率累加到其根节点(即代表名字)上。最后,输出所有有频率记录的根节点及其对应的频率。这种方法有效地将所有同义名字归并到一个名字上,并且处理了名字间的传递性等价关系。
时间复杂度: O((A + B) * α(N))
空间复杂度: O(N)
class Solution:
def trulyMostPopular(self, names: List[str], synonyms: List[str]) -> List[str]:
if len(names) <= 0:
return []
# 使用并查集来处理名字的等价关系
syn_map = dict()
for x in synonyms:
child, parent = x.split(',')
child = child.lstrip('(')
parent = parent.rstrip(')')
# 查找每个名字当前的根节点
root1 = child
while root1 in syn_map:
root1 = syn_map[root1]
root2 = parent
while root2 in syn_map:
root2 = syn_map[root2]
# 如果根节点相同,说明已在同一集合中
if root1 == root2:
continue
# 将根节点字典序较大的名字合并到字典序较小的名字下
if root1 < root2:
syn_map[root2] = root1
else:
syn_map[root1] = root2
# 统计每个根节点的频率
freq_map = dict()
for x in names:
name, freq = x.split('(')
freq = int(freq.split(')')[0])
root = name
while root in syn_map:
root = syn_map[root]
freq_map[root] = freq_map.get(root, 0) + freq
# 输出格式化的结果
return ["{}({})".format(k, v) for k, v in freq_map.items()]