解法一:并查集

参考官方题解😥。

  1. import java.util.*;
  2. import java.util.Map.Entry;
  3. class Solution {
  4. public List<List<String>> accountsMerge(List<List<String>> accounts) {
  5. Map<String, Integer> emailToIndex = new HashMap<>();
  6. Map<String, String> emailToName = new HashMap<>();
  7. int emailNum = 0;
  8. for (List<String> account : accounts) {
  9. String name = account.get(0);
  10. for (int i = 1; i < account.size(); ++i) {
  11. String email = account.get(i);
  12. if (!emailToIndex.containsKey(email)) {
  13. emailToIndex.put(email, emailNum++);
  14. emailToName.put(email, name);
  15. }
  16. }
  17. }
  18. UnionFind uf = new UnionFind(emailNum);
  19. for (List<String> account : accounts) {
  20. String firstEmail = account.get(1);
  21. int firstIndex = emailToIndex.get(firstEmail);
  22. for (int i = 2; i < account.size(); ++i) {
  23. String secondEmail = account.get(i);
  24. int secondIndex = emailToIndex.get(secondEmail);
  25. uf.union(firstIndex, secondIndex);
  26. }
  27. }
  28. Map<Integer, List<String>> indexToEmails = new HashMap<>();
  29. for (Map.Entry<String, Integer> entry : emailToIndex.entrySet()) {
  30. String email = entry.getKey();
  31. int index = uf.find(entry.getValue());
  32. List<String> list = indexToEmails.getOrDefault(index, new ArrayList<String>());
  33. list.add(email);
  34. indexToEmails.put(index, list);
  35. }
  36. List<List<String>> ans = new ArrayList<>();
  37. for (Entry<Integer, List<String>> entry : indexToEmails.entrySet()) {
  38. String name = emailToName.get(entry.getValue().get(0));
  39. List<String> list = entry.getValue();
  40. Collections.sort(list);
  41. list.add(0, name);
  42. ans.add(list);
  43. }
  44. return ans;
  45. }
  46. }
  47. class UnionFind {
  48. private int[] father;
  49. public UnionFind(int n) {
  50. father = new int[n];
  51. for (int i = 0; i < n; ++i) {
  52. father[i] = i;
  53. }
  54. }
  55. public void union(int x, int y) {
  56. father[x] = find(x);
  57. father[y] = find(y);
  58. father[father[x]] = father[y];
  59. }
  60. public int find(int x) {
  61. return father[x] == x ? x : find(father[x]);
  62. }
  63. }