Smallest Common Region
Problem
You are given some lists of regions where the first region of each list
directly contains all other regions in that list.
If a region x contains a region y directly , and region y contains region z directly , then region x is said to contain region z
indirectly. Note that region x also indirectly contains all regions
indirectly containd in y.
Naturally, if a region x contains (either directly or indirectly) another region y, then x is bigger than or equal to y in size. Also, by definition, a region x contains itself.
Given two regions: region1 and region2, return the smallest region that contains both of them.
It is guaranteed the smallest region exists.
Examples
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"
Example 2:
Input: regions = [["Earth", "North America", "South America"],["North America", "United States", "Canada"],["United States", "New York", "Boston"],["Canada", "Ontario", "Quebec"],["South America", "Brazil"]], region1 = "Canada", region2 = "South America"
Output: "Earth"
Constraints:
2 <= regions.length <= 10^42 <= regions[i].length <= 201 <= regions[i][j].length, region1.length, region2.length <= 20region1 != region2regions[i][j],region1, andregion2consist of English letters.- The input is generated such that there exists a region which contains all the other regions, either directly or indirectly.
- A region cannot be directly contained in more than one region.
Solution
Method 1 – Parent Mapping and Ancestor Path
Intuition
Build a parent map for each region. For both region1 and region2, trace their ancestors up to the root. The first common ancestor is the answer (lowest common ancestor in a tree).
Approach
- Build a map from each region to its parent.
- For region1, collect all ancestors up to the root in a set.
- For region2, walk up to the root and return the first region found in region1's ancestor set.
Code
C++
#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
using namespace std;
class Solution {
public:
string findSmallestRegion(vector<vector<string>>& regions, string region1, string region2) {
unordered_map<string, string> parent;
for (auto& reg : regions) {
for (int i = 1; i < reg.size(); ++i)
parent[reg[i]] = reg[0];
}
unordered_set<string> path;
while (region1 != "") {
path.insert(region1);
region1 = parent.count(region1) ? parent[region1] : "";
}
while (region2 != "") {
if (path.count(region2)) return region2;
region2 = parent.count(region2) ? parent[region2] : "";
}
return "";
}
};
Java
import java.util.*;
class Solution {
public String findSmallestRegion(List<List<String>> regions, String region1, String region2) {
Map<String, String> parent = new HashMap<>();
for (List<String> reg : regions) {
for (int i = 1; i < reg.size(); ++i)
parent.put(reg.get(i), reg.get(0));
}
Set<String> path = new HashSet<>();
while (region1 != null) {
path.add(region1);
region1 = parent.get(region1);
}
while (region2 != null) {
if (path.contains(region2)) return region2;
region2 = parent.get(region2);
}
return "";
}
}
Python
class Solution:
def findSmallestRegion(self, regions, region1, region2):
parent = {}
for reg in regions:
for r in reg[1:]:
parent[r] = reg[0]
path = set()
while region1:
path.add(region1)
region1 = parent.get(region1)
while region2:
if region2 in path:
return region2
region2 = parent.get(region2)
return ""
Complexity
- ⏰ Time complexity:
O(N)— N = total number of regions. - 🧺 Space complexity:
O(N)— For parent map and ancestor set.