中级农民
- 积分
- 107
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2014-5-19
- 最后登录
- 1970-1-1
|
Just my two cents: use union and find. We treat driver ID and number as the same for the sake of union and find. Later we distinguish them in the final result;
input:
Map<String, List<String>> map
output:
List<List<String>>, the numbers and uuids in one group will be in the same ArrayList. e.g. [[a, c, 1], [b, 2, 3, e], [d, 5]]
class UnionFind {
Map<String, String> parents;
public UnionFind() {
parents = new HashMap<>();
}
public String find(String u) {
while (!parents.get(u).equals(u) ) {
String p1 = parents.get(u);
String p2 = parents.get(p1);
parents.put(u, p2);
u = p1;
}
return u;
}
public void union(String u, String v) {
String pu = find(u);
String pv = find(v);
if (pu.equals(pv)) {
return;
}
// TODO, we can do union by rank here to flatten the union and find tree
parents.put(pu, pv);
}
}
List<List<String>> findRelationship(Map<String, List<String>> map) {
UnionFind set = new UnionFind();
for (String id : map.keySet()) {
set.parents.put(id, id);
List<String> numbers = map.get(id);
// assume the 0th phone number is the root;
String root = numers.get(0);
for (String num : numbers) {
set.parents.put(num, num);
set.union(num, root);
}
set.union(id, root);
}
Map<String, List<String>> groups = new HashMap<>();
for (String root : set.parents.keySet()) {
gropups.computeIfAbsent(root, k -> new ArrayList<>()).add(set.parents.get(root));
}
// final result will be [[a, c, 1], [b, 2, 3, e], [d, 5]]
// if we want to get the uuid -> phone number
// we just need to a helper function to further process each ArrayList
return new ArrayList<>(groups.entrySet());
}
|
|