1988coder

721. Accounts Merge

Dec 31st, 2018
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.94 KB | None | 0 0
  1. /**
  2.  * Using union-find with rank and path compression.
  3.  *
  4.  * Reading and adding the email to Disjoint Set using union = N operations
  5.  * Saving all emails in a set to one parent = N Operations. Thus Total 2N
  6.  * operations using Union-Find. To sort and add name to each list is O(N logN)
  7.  *
  8.  * Thus Total Time Complexity : O(N log N)
  9.  *
  10.  * Space Complexity : O(N)
  11.  *
  12.  * N = Total number of email addresses in the input.
  13.  */
  14. class Solution {
  15.     public List<List<String>> accountsMerge(List<List<String>> accounts) {
  16.         List<List<String>> result = new ArrayList();
  17.         if (accounts == null || accounts.size() == 0) {
  18.             return result;
  19.         }
  20.         if (accounts.size() == 1) {
  21.             return accounts;
  22.         }
  23.  
  24.         Map<String, Node> emailToNode = new HashMap();
  25.         Map<String, String> emailToName = new HashMap();
  26.  
  27.         // Reading all emails from the input List and adding them to Disjoint Set using
  28.         // union.
  29.         for (List<String> acc : accounts) {
  30.             if (acc.size() <= 1) {
  31.                 continue;
  32.             }
  33.             String name = acc.get(0);
  34.             String email1 = acc.get(1);
  35.             for (int i = 1; i < acc.size(); i++) {
  36.                 String email = acc.get(i);
  37.                 emailToName.put(email, name);
  38.                 if (!emailToNode.containsKey(email)) {
  39.                     emailToNode.put(email, new Node());
  40.                 }
  41.                 union(emailToNode.get(email1), emailToNode.get(email));
  42.             }
  43.         }
  44.  
  45.         Map<Node, TreeSet<String>> userGroups = new HashMap();
  46.  
  47.         // Saving all emails in a set to one parent in a hashmap.
  48.         for (String email : emailToNode.keySet()) {
  49.             Node parent = findSet(emailToNode.get(email));
  50.             if (!userGroups.containsKey(parent)) {
  51.                 userGroups.put(parent, new TreeSet<String>());
  52.             }
  53.             userGroups.get(parent).add(email);
  54.         }
  55.  
  56.         // Adding the name of the user.
  57.         for (TreeSet<String> userG : userGroups.values()) {
  58.             LinkedList<String> tempList = new LinkedList<>(userG);
  59.             tempList.addFirst(emailToName.get(tempList.get(0)));
  60.             result.add(tempList);
  61.         }
  62.  
  63.         return result;
  64.     }
  65.  
  66.     private class Node {
  67.         int rank;
  68.         Node parent;
  69.  
  70.         Node() {
  71.             rank = 0;
  72.             parent = this;
  73.         }
  74.     }
  75.  
  76.     private Node findSet(Node node) {
  77.         if (node != node.parent) {
  78.             node.parent = findSet(node.parent);
  79.         }
  80.         return node.parent;
  81.     }
  82.  
  83.     private void union(Node n1, Node n2) {
  84.         Node p1 = findSet(n1);
  85.         Node p2 = findSet(n2);
  86.  
  87.         if (p1 == p2) {
  88.             return;
  89.         }
  90.  
  91.         if (p1.rank >= p2.rank) {
  92.             p1.rank = p1.rank == p2.rank ? p1.rank + 1 : p1.rank;
  93.             p2.parent = p1;
  94.         } else {
  95.             p1.parent = p2;
  96.         }
  97.     }
  98. }
Add Comment
Please, Sign In to add comment