首页 > 代码库 > Snapchat- Group Record using Union-find

Snapchat- Group Record using Union-find

最近一直在做面筋,就没有在这边更新!但是最近!没有偷懒!

// 题目是手机上的通讯录,每条记录只有(name, number)这种pair,有些记录名字重复,有些记录号码重复,让我返回一个list<list<Record>>,
// 将所有记录按人分组。比较tricky的点在于(ABC,123), (ABC, 456), (BCD, 456)
// 三条记录,第一条和第三条也属于同一个人。要求时间复杂度尽量小

uf算法我是明白的,但是我想的时候的困惑在于

1.ufMap里面存放什么,是map<Record, Record>还是map<String, String>还是别的什么

2.在group的时候,既要对name进行uf group又要对number进行group怎么操作

 

解决方案是这样的(既union-find部分的思路)

 1 1.首先ufMap里面存<Record, Record>,初始化把所有entry过一遍,都存入,使它最初的root节点都是它自己 2  3 2. find部分。 4  5   1)首先找到这个record的root节点 6  7   2)然后把从这个record开始直到root节点所有的节点的root节点都更新成root 8  9   3)返回root10 11 3. union部分,没什么特别的12 13   1)对record1,record2找到root1,root214 15   2)如果root1 != root2,那么就设置其中一个是另外一个的root节点

 

完成union-find的部分,整个算法的整体思路是。

 1 1.建立一个nameMap<nameString, Record>和一个numMap<number, Record> 2  3 2.对于所有entry走一遍, 4  5   1) 如果nameMap里面已经存在当前entry的name,那么就说明要union;否则就把[nameString, entry]加入map 6  7   2)如果numMap里面已经存在当前entry的number,那么就说明要union;否则就把[number, entry]加入map 8 3. 所以此刻ufMap里面已经有已经对于name和number group之后的结果,现在就需要把结果保存下来。 9 10   所以可以先建一个Map<String, List<Record>>整理好,再根据这个map得到List<List<Record>>

 

实际代码如下:

 1 public class GroupRecord { 2     static class Record { 3         String name; 4         int number; 5         public Record(String name, int number) { 6             this.name = name; 7             this.number = number; 8         } 9         10         public String toString() {11             return "(" + name + "," + number + ")";12         }13     }14     15     public static List<List<Record>> group(List<Record> records) {16         Map<Record, Record> ufMap = new HashMap<Record, Record>();17         Map<String, Record> nameMap = new HashMap<>();18         Map<Integer, Record> numMap = new HashMap<>();19         for(Record entry: records) {20             ufMap.put(entry, entry);21         }22         for(Record entry: records) {23             if(nameMap.containsKey(entry.name)) {24                 union(ufMap, entry, nameMap.get(entry.name));25             } else {26                 nameMap.put(entry.name, entry);27             }28             if(numMap.containsKey(entry.number)) {29                 union(ufMap, entry, numMap.get(entry.number));30             } else {31                 numMap.put(entry.number, entry);32             }33         }34         Map<String, List<Record>> groupMap = new HashMap<>();35         for(Record entry: records) {36             Record root = find(ufMap, entry);37             List<Record> list = groupMap.get(root.name);38             if(list == null) {39                 list = new ArrayList<Record>();40             }41             list.add(entry);42             groupMap.put(root.name, list);43         }44         List<List<Record>> res = new ArrayList<List<Record>>(groupMap.values());45         return res;46     }47     48     private static Record find(Map<Record, Record> ufMap, Record record) {49         Record root = record;50         while(!ufMap.get(root).equals(root)) {51             root = ufMap.get(root);52         }53         Record cur = record;54         while(!cur.equals(root)) {55             ufMap.put(record, root);56             cur = ufMap.get(cur);57         }58         return root;59     }60     61     private static void union(Map<Record, Record> ufMap, Record r1, Record r2) {62         Record root1 = find(ufMap, r1);63         Record root2 = find(ufMap, r2);64         if(!root1.equals(root2)) {65             ufMap.put(root1, root2);66         }67     }68 69     public static void main(String[] args) {70         List<List<Record>> res = new ArrayList<List<Record>>();71         ArrayList<Record> records = new ArrayList<>();72         records.add(new Record("ABC",123));73         records.add(new Record("ABC",456));74         records.add(new Record("BCD",456));75 76         records.add(new Record("AD",342));77         records.add(new Record("AddD",11));78         records.add(new Record("DFX",34));79         records.add(new Record("AD",34));80         records.add(new Record("AD",11));81         82         res = group(records);83         System.out.println(res);84     }85 }

 

Snapchat- Group Record using Union-find