题目

每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量。有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来。给定两个列表,一个是名字及对应的频率,另一个是本质相同的名字对。设计一个算法打印出每个真实名字的实际频率。注意,如果 John 和 Jon 是相同的,并且 Jon 和 Johnny 相同,则 John 与 Johnny 也相同,即它们有传递和对称性。

在结果列表中,选择字典序最小的名字作为真实名字。

示例:

输入:names =
[“John(15)”,“Jon(12)”,“Chris(13)”,“Kris(4)”,“Christopher(19)”],
synonyms =
["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Chris,Christopher)"]
输出:[“John(27)”,“Chris(36)”]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/baby-names-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


使用并查集求解,将names中的每个婴儿名字作为并查集的元素,通过遍历synonyms合并相同的婴儿名字,即确定元素间的父子关系,在合并时(即union函数),首先找到两个婴儿名字的祖宗,并将祖宗名字小的作为新的祖宗(题目要求选择字典序最小的名字作为真实名字)。

确定父子关系后,统计婴儿名字的频率,统计时先找到该名字的祖宗,然后将该名字的频率叠加到祖宗名字的频率上

class UnionFindSet {int parent[];public UnionFindSet(int n) {parent = new int[n];for (int i = 0; i < n; i++)parent[i] = -1;}public int find(int i) {if (parent[i] < 0)return i;parent[i] = find(parent[i]);return parent[i];}public void union(int i, int j, Map<Integer, String> nameIdx) {// 合并i和j, 并且让i j中祖宗的字典序最小的作为父亲, 并返回父亲坐标int ii = find(i);int jj = find(j);String nameii = nameIdx.get(ii);String namejj = nameIdx.get(jj);if (ii != jj) {if (nameii.compareTo(namejj) < 0)// nameii < namejj, let ii be the father.parent[jj] = ii;elseparent[ii] = jj;}}
}class Solution {public String[] trulyMostPopular(String[] names, String[] synonyms) {/*** 输入:names = ["John(15)","Jon(12)","Chris(13)","Kris(4)","Christopher(19)"],* synonyms = ["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Kris,Christopher)"]* 输出:["John(27)","Chris(36)"]*/int n = names.length;UnionFindSet ufset = new UnionFindSet(n);Map<String, Integer> nameIndexMap = new HashMap();Map<Integer, String> indexnameMap = new HashMap();for (int i = 0; i < n; i++) {// get nameint idx1 = names[i].indexOf('(');int idx2 = names[i].indexOf(')');String name = names[i].substring(0, idx1);nameIndexMap.put(name, i);indexnameMap.put(i, name);}for (String pair : synonyms) {int idx1 = pair.indexOf('(');int idx2 = pair.indexOf(',');int idx3 = pair.indexOf(')');String name1 = pair.substring(idx1 + 1, idx2);String name2 = pair.substring(idx2 + 1, idx3);if (nameIndexMap.containsKey(name1) && nameIndexMap.containsKey(name2)) {int id1 = nameIndexMap.get(name1), id2 = nameIndexMap.get(name2);ufset.union(id1, id2, indexnameMap);}}Map<String, Integer> nameFreqMap = new HashMap<>();for (int i = 0; i < n; i++) {int f = ufset.find(i);// get frequency of name i.int freqi = Integer.valueOf(names[i].substring(names[i].indexOf('(') + 1, names[i].indexOf(')')));String namef = names[f].substring(0, names[f].indexOf('('));if (nameFreqMap.containsKey(namef)) {int count = nameFreqMap.get(namef) + freqi;nameFreqMap.remove(namef);nameFreqMap.put(namef, count);} else {nameFreqMap.put(namef, freqi);}}String res[] = new String[nameFreqMap.size()];int i = 0;for (String key : nameFreqMap.keySet()) {String tmp = key + '(' + nameFreqMap.get(key).toString() + ')';res[i] = tmp;i++;}return res;}
}

这里主要用到字符串的indexOfsubstring等操作

【并查集】面试题 17.07. 婴儿名字相关推荐

  1. 并查集之面试题 17.07. 婴儿名字

    并查集之面试题 17.07. 婴儿名字 前言 一, 面试题 17.07. 婴儿名字 二,解题思路 1, a和b是朋友, b和c是朋友,那a和c也是朋友.这就是典型并查集类型 2, 字典序 3, 三, ...

  2. [Leetcode 每日精选](本周主题-并查集) 面试题 17.07. 婴儿名字

    题目难度: 中等 原题链接 今天继续来做并查集的问题, 这道题多了一些变化, 但核心仍然是并查集. 大家在我的公众号"每日精选算法题"中的聊天框中回复 并查集 就能看到该系列当前已 ...

  3. 面试题.17.07.婴儿名字--并查集

    LeetCode 面试题 17.07.婴儿名字 每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量.有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被 ...

  4. 面试题 17.07. 婴儿名字 ( 字符标志 并查集 )

    面试题 17.07. 婴儿名字 字符串并查集: 721. 账户合并 ( 并查集 ) 解题思路: 首先通过哈希表建立并查集,哈希表的键值对都是字符串,然后将一个相连的并查集合并: 利用一个哈希表进行计数 ...

  5. [LeetCode][C++]面试题 17.07. 婴儿名字/并查集

    面试题 17.07. 婴儿名字 每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量.有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公 ...

  6. 面试题 17.07. 婴儿名字

    面试题 17.07. 婴儿名字 每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量.有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公 ...

  7. leetcode面试题 17.07. 婴儿名字(并查集)

    每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量.有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来.给定两个列表,一个是名字 ...

  8. 程序员面试金典 - 面试题 17.07. 婴儿名字(并查集)

    1. 题目 每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量. 有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来. 给定两个 ...

  9. leetcode:面试题 17.07. 婴儿名字(并查集,代码超时了)

    题目: 分析: 并查集. 我用python写的, 1.创建一个二维列表,然后每个列表中的元素都只有一个,为每个名字. 2.查synonyms,匹配的名字对应的列表合并. 3.排序,求和. 竟然超时了, ...

最新文章

  1. 时空上下文视觉跟踪(STC)算法的解读与代码复现
  2. Java数三退一问题代码_数三退一问题算法(Java)
  3. C#:导入Excel通用类(CSV格式)
  4. a data source instance has not been supplied for the datasource 'dataset1'. rdlc
  5. java判断字符串是否为数字或中文或字母
  6. python中 [ 闭包 ] 小结
  7. 北师大网络教育计算机试题一的答案,北师大网络教育《专科英语一》作业3部分答案...
  8. iOS开发--完整项目
  9. myeclipse 发布 web 项目后 tomcat 无法正常启动
  10. 视频截取图片帧工具(可免费使用)
  11. 【RFID】RFID的标准体系
  12. Word上下标快捷键
  13. 有量纲和无量纲是什么意思_为什么无线通信需要同步?
  14. 博客园签名档图片圆角美化
  15. 【Python项目】你们还在冲会员看电影电视剧嘛?Python带你免费看电影电视剧资源 | 附源码
  16. ftp 文件夹 上传到服务器,ftp上传文件夹到服务器 远程路径
  17. 想自己动手制作游戏动漫角色模型,教你几招,一定要看看!
  18. new BigDecimal比较大小
  19. 幼儿抽象逻辑思维举例_孩子这五大表现,证明抽象思维萌发,家长一定要抓住这个关键时机...
  20. GitChat软件中的课程、专栏下载脚本,包含各种格式(pdf、markdown)

热门文章

  1. 20193月计算机二级选择题,2019年3月计算机二级选择题1-10,关注我持续更新!!...
  2. netty write 和flush 源码解析
  3. Ubuntu 20.04向日葵远程下载及安装记录
  4. 将Excel导入DataGridView 中的select * from [Sheet1$]中[ ]里面表单名的动态获取
  5. 企业公司邮箱 | 什么是邮件归档和邮件备份?
  6. 设计模式--类图、实例代码
  7. 安卓高级8 SurfaceView案例三 结合mediaplay播放视频
  8. python字体描边_艺术字体生成器下载
  9. 【题解】CF1770E Koxia and Tree
  10. 十道腾讯软件开发工程师面试题