Smallest Common Region

medium tree lowest common ancestor hash map

Problem

You are given a list of regions where each entry lists a parent region followed by its direct sub-regions. Region X contains region Y if X is the same as Y or X transitively contains Y. Given two regions region1 and region2, return the smallest region that contains both of them.

Inputregions = [[Earth,NA,SA],[NA,US,Canada],[US,NY,SF]], region1 = SF, region2 = Canada
OutputNA
SF sits under US under NA; Canada sits directly under NA. Their lowest common ancestor is NA.

def find_smallest_region(regions, region1, region2):
    parent = {}
    for group in regions:
        for child in group[1:]:
            parent[child] = group[0]
    ancestors = set()
    node = region1
    while node:
        ancestors.add(node)
        node = parent.get(node)
    node = region2
    while node not in ancestors:
        node = parent.get(node)
    return node
function findSmallestRegion(regions, region1, region2) {
  const parent = new Map();
  for (const group of regions)
    for (let i = 1; i < group.length; i++) parent.set(group[i], group[0]);
  const ancestors = new Set();
  for (let node = region1; node; node = parent.get(node)) ancestors.add(node);
  let node = region2;
  while (!ancestors.has(node)) node = parent.get(node);
  return node;
}
class Solution {
    public String findSmallestRegion(List<List<String>> regions, String region1, String region2) {
        Map<String, String> parent = new HashMap<>();
        for (List<String> group : regions)
            for (int i = 1; i < group.size(); i++) parent.put(group.get(i), group.get(0));
        Set<String> ancestors = new HashSet<>();
        for (String node = region1; node != null; node = parent.get(node)) ancestors.add(node);
        String node = region2;
        while (!ancestors.contains(node)) node = parent.get(node);
        return node;
    }
}
string findSmallestRegion(vector<vector<string>>& regions, string region1, string region2) {
    unordered_map<string, string> parent;
    for (auto& group : regions)
        for (int i = 1; i < (int)group.size(); i++) parent[group[i]] = group[0];
    unordered_set<string> ancestors;
    for (string node = region1; !node.empty(); node = parent.count(node) ? parent[node] : "")
        ancestors.insert(node);
    string node = region2;
    while (!ancestors.count(node)) node = parent[node];
    return node;
}
Time: O(N + h) Space: O(N)