class Solution { Map<String,String> emails; public List<List<String>> accountsMerge(List<List<String>> accounts) { if(accounts.size()==1){ return accounts; } emails=new HashMap<>(); Map<String,String> names=new HashMap<>(); //建立所有邮箱的并查集,初始时刻根节点是他本身 for(List<String> list:accounts){ for(int i=1;i<list.size();i++){ if(!emails.containsKey(list.get(i))){ emails.put(list.get(i), list.get(i)); names.put(list.get(i),list.get(0)); } //合并同一个账户的email if(i>1){ emails.put(find(list.get(i)), find(list.get(i-1))); } } } //邮箱合并 Map<String,List<String>> temp=new HashMap<>(); for(String s:emails.keySet()){ String root=find(s); if(!temp.containsKey(root)){ temp.put(root, new ArrayList<>()); } temp.get(root).add(s); } //构建结果list,其中只需要知道每个root的name就好 List<List<String>> result=new ArrayList<>(); for(String root:temp.keySet()){ List<String> t=temp.get(root); Collections.sort(t); t.add(0,names.get(root)); result.add(t); } return result; } public String find(String x){ if(!emails.get(x).equals(x)) { emails.put(x, find(emails.get(x))); } return emails.get(x); } }
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该账户的邮箱地址。
现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。请注意,即使两个账户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的账户,但其所有账户都具有相同的名称。
合并账户后,按以下格式返回账户:每个账户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。账户本身可以以任意顺序返回。
思路:
用email作为key,建立每个email的初始并查集,首先合并每个用户的email到一个并查集,之后大范围合并,对于name到email,只需要知道根的name就好