最近一直在做面筋,就没有在这边更新!但是最近!没有偷懒!
// 题目是手机上的通讯录,每条记录只有(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)返回root 10 11 3. union部分,没什么特别的 12 13 1)对record1,record2找到root1,root2 14 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 }
时间: 2024-12-05 23:14:59