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就好