给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该账户的邮箱地址。
现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。请注意,即使两个账户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的账户,但其所有账户都具有相同的名称。
合并账户后,按以下格式返回账户:每个账户的第一个元素是名称,其余元素是按字符 ASCII 顺序排列的邮箱地址。账户本身可以以任意顺序返回。
示例 1:
输入:
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”]]
解释:
第一个和第三个 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’]] 也是正确的。
代码
class Solution {int[] fa;public void init(){for(int i=0;i<fa.length;i++)fa[i]=i;}public int find(int x){if(x!=fa[x])fa[x]=find(fa[x]);return fa[x];}public void union(int x,int y){x=find(x);y=find(y);if(x==y) return;fa[x]=y;}public List<List<String>> accountsMerge(List<List<String>> accounts) {Map<String,Integer> index=new HashMap<>();Map<Integer,String> name=new HashMap<>();int inx=0;for(List<String> list:accounts){String accName=list.get(0);for(int i=1;i<list.size();i++)if(!index.containsKey(list.get(i))) {//为每个邮箱地址创建下标和姓名映射name.put(inx,accName);index.put(list.get(i), inx++);}}fa=new int[inx];init();for(List<String> list:accounts)//将具有相同邮箱的 连接起来{int father=index.get(list.get(1));for(int i=2;i<list.size();i++)union(index.get(list.get(i)),father);}Map<Integer,List<String>> map=new HashMap<>();for(String s:index.keySet())//创建每个集合中 父节点下标 对 所有邮箱地址的映射{int fa=find(index.get(s));List<String> list=map.getOrDefault(fa,new ArrayList<>());list.add(s);map.put(fa,list);}List<List<String>> res=new ArrayList<>();for(int f:map.keySet())//按特定格式 写入结果{List<String> temp=new ArrayList<>();List<String> email=map.get(f);Collections.sort(email);temp.add(name.get(f));temp.addAll(email);res.add(temp);}return res;}
}