给定一个列表 accounts
,每一个元素 accounts[i]
是一个字符串列表,其中第一个元素 accounts[i][0]
是 名称 (name),其他元素是 emails,表示该帐户的邮箱地址。java
如今,咱们想合并这些帐户。若是两个帐户都有一些共同的邮箱地址,则两个帐户一定属于同一我的。请注意,即便两个帐户具备相同的名称,它们也可能属于不一样的人,由于人们可能具备相同的名称。一我的最初能够拥有任意数量的帐户,但其全部帐户都具备相同的名称。.net
合并帐户后,按如下格式返回帐户:每一个帐户的第一个元素是名称,其他元素是按字符 ASCII 顺序排列的邮箱地址。帐户自己能够以任意顺序返回。code
示例 1:blog
输入:
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]字符串
输出: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]get
解释:
第一个和第三个 John 是同一我的,由于他们有共同的邮箱地址 "johnsmith@mail.com"。
第二个 John 和 Mary 是不一样的人,由于他们的邮箱地址没有被其余账户使用。
能够以任何顺序返回这些列表,例如答案 [['Mary','mary@mail.com'],['John','johnnybravo@mail.com'],
['John','john00@mail.com','john_newyork@mail.com','johnsmith@mail.com']] 也是正确的。博客
提示:it
accounts
的长度将在 [1,1000]
的范围内。accounts[i]
的长度将在 [1,10]
的范围内。accounts[i][j]
的长度将在 [1,30]
的范围内。本题能够使用并查集解决,具体什么是并查集,能够看看这篇博客 https://blog.csdn.net/bjweimengshu/article/details/108332389io
根据题目要求,两个帐户只要有一个邮箱相同,那么就认为是同一我的,所以咱们如下标表示用户,把全部属于同一我的的用户(下标)使用并查集链接起来,接下来嘛 。。。我也不知道怎么描述,看代码吧class
class Solution { public List<List<String>> accountsMerge(List<List<String>> accounts) { // 建立一个 HashMap,经过下列的循环操做能够得知 // 最终每一个邮箱都会对应它所属的某一个用户id Map<String, Integer> emailToId = new HashMap<>(); int accountsLen = accounts.size(); UnionFind union = new UnionFind(accountsLen); for(int i = 0; i < accountsLen; i++) { int emailsLen = accounts.get(i).size(); for(int j = 1; j < emailsLen; j++) { String curEmail = accounts.get(i).get(j); if(emailToId.containsKey(curEmail)) { union.merge(emailToId.get(curEmail), i); } else { emailToId.put(curEmail, i); } } } // 将用户id与其拥有的全部email对应起来 Map<Integer, List<String>> idToEmail = new HashMap<>(); for(Map.Entry<String, Integer> entry : emailToId.entrySet()) { // 首先要找到父id int id = union.getFather(entry.getValue()); // 父id拥有的emails必定是链接集合中全部用户所共有的 List<String> emails = idToEmail.getOrDefault(id, new LinkedList<>()); // 再把缺乏的email添加到emails中 emails.add(entry.getKey()); idToEmail.put(id, emails); } // 将id与用户名对应便可 List<List<String>> result = new LinkedList<>(); for (Map.Entry<Integer,List<String>> entry : idToEmail.entrySet()) { List<String> list = entry.getValue(); Collections.sort(list); list.add(0, accounts.get(entry.getKey()).get(0)); result.add(list); } return result; } class UnionFind { int[] f; public UnionFind(int n) { f = new int[n]; for(int i = 0; i < n; i++) { f[i] = i; } } public int getFather(int index) { return f[index] == index ? index : getFather(f[index]); } public void merge(int index1, int index2) { f[getFather(index1)] = getFather(index2); } } }