Graph Connected Components的题目。We can use both union-find and DFS algorithms.
Referred to this post and this video solution.
Treat each email accounts group (an entity in the given input accounts) as a component, we want to find all connected components among these email accounts. Two components are connected if they have any emails in common.
class Solution {
public List<List<String>> accountsMerge(List<List<String>> accounts) {
Map<String, Set<String>> graph = new HashMap<>(); // <email node, neighbor nodes>
Map<String, String> emailToName = new HashMap<>(); // <email, name>
buildGraph(graph, emailToName, accounts);
List<List<String>> res = new ArrayList<>();
Set<String> visited = new HashSet<>();
// DFS search the graph;
for (String mail : emailToName.keySet()) {
if (!visited.contains(mail)) {
visited.add(mail);
List<String> list = new ArrayList<>();
list.add(mail);
dfs(graph, list, mail, visited);
Collections.sort(list);
list.add(0, emailToName.get(mail));
res.add(list);
}
}
return res;
}
// For each account, draw the edge from the first email to all other emails.
// Additionally, we'll remember a map from emails to names on the side.
private void buildGraph(Map<String, Set<String>> graph, Map<String, String> emailToName, List<List<String>> accounts) {
for (List<String> account : accounts) {
String name = account.get(0);
for (int i = 1; i < account.size(); i++) {
String mail = account.get(i);
emailToName.put(mail, name);
graph.putIfAbsent(mail, new HashSet<>());
if (i == 1) {
continue;
}
String prev = account.get(i - 1);
graph.get(prev).add(mail);
graph.get(mail).add(prev);
}
}
}
// After finding each connected component using a depth-first search, we'll add that to our answer.
private void dfs(Map<String, Set<String>> graph, List<String> list, String mail, Set<String> visited) {
if (graph.get(mail) == null || graph.get(mail).size() == 0) {
return;
}
for (String neighbor : graph.get(mail)) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
list.add(neighbor);
dfs(graph, list, neighbor, visited);
}
}
}
}
TODO. To refer to this post.