--- link: https://leetcode.com/problems/smallest-common-region/ tags: array, matrix, tree, adjacency list, medium --- # 1257. Smallest Common Region ## Question You are given some lists of `regions` where the first region of each list includes all other regions in that list. Naturally, if a region `X` contains another region `Y` then `X` is bigger than `Y`. Also by definition a region X contains itself. Given two regions `region1`, `region2`, find out the **smallest** region that contains both of them. If you are given regions `r1`, `r2` and `r3` such that `r1` includes `r3`, it is guaranteed there is no `r2` such that `r2` includes `r3`. It's guaranteed the smallest region exists. **Example 1:** ``` Input: regions = [["Earth","North America","South America"], ["North America","United States","Canada"], ["United States","New York","Boston"], ["Canada","Ontario","Quebec"], ["South America","Brazil"]], region1 = "Quebec", region2 = "New York" Output: "North America" ``` **Constraints:** - `2 <= regions.length <= 10^4` - `region1 != region2` - All strings consist of English letters and spaces with at most 20 letters. ## Solution: Python ```python= class Solution(object): def findSmallestRegion(self, regions, region1, region2): """ :type regions: List[List[str]] :type region1: str :type region2: str :rtype: str """ root = self.constructNaryTree(regions) self.smallest_region = None self.helper(root, region1, region2) return self.smallest_region.region if self.smallest_region else None def helper(self, node, region1, region2): if node is None: return False, False found_region_1, found_region_2 = node.region == region1, node.region == region2 if found_region_1 and found_region_2: self.smallest_region = node return False, False for subregion in node.subregions.values(): subregion_found_region_1, subregion_found_region_2 = self.helper( subregion, region1, region2 ) found_region_1 = found_region_1 or subregion_found_region_1 found_region_2 = found_region_2 or subregion_found_region_2 if found_region_1 and found_region_2: self.smallest_region = node return False, False return found_region_1, found_region_2 def constructNaryTree(self, regions): nodes = {} root = None for region in regions: key = region[0] node = nodes.get(key, TreeNode(region=key)) nodes[key] = node if root is None: root = node for idx in xrange(1, len(region)): subregion_node = nodes.get(region[idx], TreeNode(region=region[idx])) nodes[region[idx]] = subregion_node node.subregions[region[idx]] = subregion_node return root class TreeNode(): def __init__(self, region): self.region = region self.subregions = {} def __str__(self): return str(self.__dict__) # solution = Solution() # regions = [["Earth","North America","South America"],["North America","United States","Canada"],["United States","New York","Boston"],["Canada","Ontario","Quebec"],["South America","Brazil"]] # region_1 = "Quebec" # region_2 = "New York" # print solution.findSmallestRegion(regions, region_1, region_2) ```