5109. 最小公共区域

给你一些区域列表 regions ,每个列表的第一个区域都包含这个列表内所有其他区域。

很自然地,如果区域 X 包含区域 Y ,那么区域 X  比区域 Y 大。

给定两个区域 region1 和 region2 ,找到同时包含这两个区域的 最小 区域。

如果区域列表中 r1 包含 r2 和 r3 ,那么数据保证 r2 不会包含 r3 。

数据同样保证最小公共区域一定存在。

 

示例 1:

输入:
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"
输出:"North America"
 

提示:

2 <= regions.length <= 10^4
region1 != region2
所有字符串只包含英文字母和空格,且最多只有 20 个字母。

题解:

遍历区域节点建立父节点的映射字典`p`,然后把`rigion1`的所有祖先节点装进集合`q`,再遍历`rigion2`的祖先节点,如果其存在于`q`,则为最近公共祖先。

为了方便代码阅读,把`rigion`简写成了`r`。

时间复杂度和空间复杂度都是$O(N)$其中$N$为`regions`的子条目数量,264ms仅供参考。

class Solution:
    def findSmallestRegion(self, regions: List[List[str]], r1: str, r2: str) -> str:
        q, p = set(), {i: j for j, *r in regions for i in r}
        while r1 in p:
            q.add(r1)
            r1 = p[r1]
        while r2 in p:
            if r2 in q:
                return r2
            r2 = p[r2]
        return r2

 

#第二次`while`循环之前令`q = {*p.keys()} - q`。
#方便控制节点存在于`p`不存在`q`时的`while`循环。
class Solution:
    def findSmallestRegion(self, regions: List[List[str]], r1: str, r2: str) -> str:
        q, p = set(), {i: j for j, *r in regions for i in r}    #其中i为区域,j为对应的直接父节点,通过(j, *r)分离出数组的第一个元素和后续元素。
        while r1 in p:
            q.add(r1)
            r1 = p[r1]
        q = {*p.keys()} - q
        while r2 in q:
            r2 = p[r2]
        return r2

 

你可能感兴趣的:(5109. 最小公共区域)