Snapchat- Group Record using Union-find


Related: Group Contacts | tech::interview
https://warmland.gitbooks.io/algorithm/content/interview/snapchat-_group_record_using_union-find.html
// 题目是手机上的通讯录,每条记录只有(name, number)这种pair,有些记录名字重复,有些记录号码重复,让我返回一个list>, // 将所有记录按人分组。比较tricky的点在于(ABC,123), (ABC, 456), (BCD, 456) // 三条记录,第一条和第三条也属于同一个人。要求时间复杂度尽量小
uf算法我是明白的,但是我想的时候的困惑在于
1.ufMap里面存放什么,是map还是map还是别的什么
2.在group的时候,既要对name进行uf group又要对number进行group怎么操作
解决方案是这样的(既union-find部分的思路)
1.首先ufMap里面存<Record, Record>,初始化把所有entry过一遍,都存入,使它最初的root节点都是它自己

2. find部分。

  1)首先找到这个record的root节点

  2)然后把从这个record开始直到root节点所有的节点的root节点都更新成root

  3)返回root

3. union部分,没什么特别的

  1)对record1,record2找到root1,root2

  2)如果root1 != root2,那么就设置其中一个是另外一个的root节点
完成union-find的部分,整个算法的整体思路是。
1.建立一个nameMap<nameString, Record>和一个numMap<number, Record>

2.对于所有entry走一遍,

  1) 如果nameMap里面已经存在当前entry的name,那么就说明要union;否则就把[nameString, entry]加入map

  2)如果numMap里面已经存在当前entry的number,那么就说明要union;否则就把[number, entry]加入map
3. 所以此刻ufMap里面已经有已经对于name和number group之后的结果,现在就需要把结果保存下来。

  所以可以先建一个Map<String, List<Record>>整理好,再根据这个map得到List<List<Record>>
实际代码如下:
public class GroupRecord {
    static class Record {
        String name;
        int number;
        public Record(String name, int number) {
            this.name = name;
            this.number = number;
        }

        public String toString() {
            return "(" + name + "," + number + ")";
        }
    }

    public static List<List<Record>> group(List<Record> records) {
        Map<Record, Record> ufMap = new HashMap<Record, Record>();
        Map<String, Record> nameMap = new HashMap<>();
        Map<Integer, Record> numMap = new HashMap<>();
        for(Record entry: records) {
            ufMap.put(entry, entry);
        }
        for(Record entry: records) {
            if(nameMap.containsKey(entry.name)) {
                union(ufMap, entry, nameMap.get(entry.name));
            } else {
                nameMap.put(entry.name, entry);
            }
            if(numMap.containsKey(entry.number)) {
                union(ufMap, entry, numMap.get(entry.number));
            } else {
                numMap.put(entry.number, entry);
            }
        }
        Map<String, List<Record>> groupMap = new HashMap<>();
        for(Record entry: records) {
            Record root = find(ufMap, entry);
            List<Record> list = groupMap.get(root.name);
            if(list == null) {
                list = new ArrayList<Record>();
            }
            list.add(entry);
            groupMap.put(root.name, list);
        }
        List<List<Record>> res = new ArrayList<List<Record>>(groupMap.values());
        return res;
    }

    private static Record find(Map<Record, Record> ufMap, Record record) {
        Record root = record;
        while(!ufMap.get(root).equals(root)) {
            root = ufMap.get(root);
        }
        Record cur = record;
        while(!cur.equals(root)) {
            ufMap.put(record, root);
            cur = ufMap.get(cur);
        }
        return root;
    }

    private static void union(Map<Record, Record> ufMap, Record r1, Record r2) {
        Record root1 = find(ufMap, r1);
        Record root2 = find(ufMap, r2);
        if(!root1.equals(root2)) {
            ufMap.put(root1, root2);
        }
    }

    public static void main(String[] args) {
        List<List<Record>> res = new ArrayList<List<Record>>();
        ArrayList<Record> records = new ArrayList<>();
        records.add(new Record("ABC",123));
        records.add(new Record("ABC",456));
        records.add(new Record("BCD",456));

        records.add(new Record("AD",342));
        records.add(new Record("AddD",11));
        records.add(new Record("DFX",34));
        records.add(new Record("AD",34));
        records.add(new Record("AD",11));

        res = group(records);
        System.out.println(res);
    }
}

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts