题目描述
每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量。有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来。给定两个列表,一个是名字及对应的频率,另一个是本质相同的名字对。设计一个算法打印出每个真实名字的实际频率。注意,如果 John 和 Jon 是相同的,并且 Jon 和 Johnny 相同,则 John 与 Johnny 也相同,即它们有传递和对称性。
在结果列表中,选择字典序最小的名字作为真实名字。
力扣:面试题17.07 婴儿名字
示例:
输入:
names = [“John(15)”,“Jon(12)”,“Chris(13)”,“Kris(4)”,“Christopher(19)”],
synonyms = ["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Chris,Christopher)"]
输出:
[“John(27)”,“Chris(36)”]
题目分析
本题采用的是 并查集 进行求解
1、首先通过 names 列表,构建出每个单独的节点, 即自身为自己的父节点 ;
2、通过 synonyms 列表,构建节点之间的关系,字典序最小的为根节点 ;
3、将每个孩子节点的频率 , 累加到父节点 ,求得实际频率;
这题通过 Map 对数据进行存储,和平常的整数类型的并查集,写法只需稍微注意即可
主要麻烦在,对字符串的处理过程。
AC代码:
class Solution {
public String find(Map<String , String> parent , String name){
// 这里和整数类型并查集有区别 return fa[i] == -1 ? i : find(fa , fa[i]);
// 此题的终止是, key 值和 value 值相同,说明到了根部
if(parent.get(name).equals(name))
return name;
else return find(parent , parent.get(name));
}
public void union(Map<String , String> parent , String firstName , String secondName){