解法一:并查集
参考官方题解😥。
import java.util.*;
import java.util.Map.Entry;
class Solution {
public List<List<String>> accountsMerge(List<List<String>> accounts) {
Map<String, Integer> emailToIndex = new HashMap<>();
Map<String, String> emailToName = new HashMap<>();
int emailNum = 0;
for (List<String> account : accounts) {
String name = account.get(0);
for (int i = 1; i < account.size(); ++i) {
String email = account.get(i);
if (!emailToIndex.containsKey(email)) {
emailToIndex.put(email, emailNum++);
emailToName.put(email, name);
}
}
}
UnionFind uf = new UnionFind(emailNum);
for (List<String> account : accounts) {
String firstEmail = account.get(1);
int firstIndex = emailToIndex.get(firstEmail);
for (int i = 2; i < account.size(); ++i) {
String secondEmail = account.get(i);
int secondIndex = emailToIndex.get(secondEmail);
uf.union(firstIndex, secondIndex);
}
}
Map<Integer, List<String>> indexToEmails = new HashMap<>();
for (Map.Entry<String, Integer> entry : emailToIndex.entrySet()) {
String email = entry.getKey();
int index = uf.find(entry.getValue());
List<String> list = indexToEmails.getOrDefault(index, new ArrayList<String>());
list.add(email);
indexToEmails.put(index, list);
}
List<List<String>> ans = new ArrayList<>();
for (Entry<Integer, List<String>> entry : indexToEmails.entrySet()) {
String name = emailToName.get(entry.getValue().get(0));
List<String> list = entry.getValue();
Collections.sort(list);
list.add(0, name);
ans.add(list);
}
return ans;
}
}
class UnionFind {
private int[] father;
public UnionFind(int n) {
father = new int[n];
for (int i = 0; i < n; ++i) {
father[i] = i;
}
}
public void union(int x, int y) {
father[x] = find(x);
father[y] = find(y);
father[father[x]] = father[y];
}
public int find(int x) {
return father[x] == x ? x : find(father[x]);
}
}