Union-find on emails
Time O(E log E) for sorting, E = total emails Space O(E)Map email → id and email → name. Union each account's emails with its first one. Group emails by root into TreeSets, then prepend the name.
import java.util.*;
class Solution {
private int[] parent;
public List<List<String>> accountsMerge(List<List<String>> accounts) {
Map<String, Integer> id = new HashMap<>();
Map<String, String> owner = new HashMap<>();
for (List<String> acc : accounts)
for (int i = 1; i < acc.size(); i++) {
id.putIfAbsent(acc.get(i), id.size());
owner.put(acc.get(i), acc.get(0));
}
parent = new int[id.size()];
for (int i = 0; i < parent.length; i++) parent[i] = i;
for (List<String> acc : accounts)
for (int i = 2; i < acc.size(); i++)
parent[find(id.get(acc.get(i)))] = find(id.get(acc.get(1)));
Map<Integer, TreeSet<String>> groups = new HashMap<>();
for (String email : id.keySet())
groups.computeIfAbsent(find(id.get(email)), k -> new TreeSet<>()).add(email);
List<List<String>> out = new ArrayList<>();
for (TreeSet<String> emails : groups.values()) {
List<String> row = new ArrayList<>();
row.add(owner.get(emails.first()));
row.addAll(emails);
out.add(row);
}
return out;
}
private int find(int x) {
while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; }
return x;
}
}Verdict: Merging is near-linear; sorting dominates.