最小公共区域
难度:
标签:
题目描述
代码结果
运行时间: 41 ms, 内存: 19.2 MB
/*
* Leetcode 1257: Smallest Common Region
*
* Given a list of regions where the first region in each list includes all other regions in that list, find the smallest region that contains both given regions.
*
* Steps to solve the problem:
* 1. Use a map to keep track of each region and its parent region.
* 2. Find the path from each given region to the root region and store it in a set.
* 3. Traverse the path from one region and check for the first common region in the set of the other region.
*/
import java.util.*;
import java.util.stream.Collectors;
public class SmallestCommonRegionStream {
public String findSmallestRegion(List<List<String>> regions, String region1, String region2) {
Map<String, String> parentMap = regions.stream()
.flatMap(list -> list.subList(1, list.size()).stream().map(region -> new AbstractMap.SimpleEntry<>(region, list.get(0))))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Set<String> pathToRoot1 = new HashSet<>();
while (region1 != null) {
pathToRoot1.add(region1);
region1 = parentMap.get(region1);
}
while (region2 != null) {
if (pathToRoot1.contains(region2)) {
return region2;
}
region2 = parentMap.get(region2);
}
return null; // Should never reach here if input is valid
}
public static void main(String[] args) {
List<List<String>> regions = Arrays.asList(
Arrays.asList("Earth", "North America", "South America"),
Arrays.asList("North America", "United States", "Canada"),
Arrays.asList("United States", "California", "Texas"),
Arrays.asList("Canada", "Ontario", "Quebec"),
Arrays.asList("South America", "Brazil", "Argentina")
);
SmallestCommonRegionStream solver = new SmallestCommonRegionStream();
System.out.println(solver.findSmallestRegion(regions, "California", "Quebec")); // Output: North America
}
}
解释
方法:
本题目的是找到两个区域r1和r2的最小公共区域。首先,根据regions列表建立一个字典p,键为区域名,值为该区域的直接父区域。然后,从r1开始,逐级向上追溯其父区域,并将遇到的每个区域存储在集合q中。之后,从r2开始向上追溯其父区域,直到找到第一个同时存在于集合q中的区域,即为最小公共区域。如果r2的所有父区域都不在集合q中,则返回最顶层的父区域r2。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在构建父区域字典`p`时,对于包含多个子区域的列表项,如何确保字典正确反映了所有子区域到父区域的映射?
▷🦆
代码中没有显式地处理r1或r2为顶级区域的情况,这是否意味着算法假设输入的r1和r2总是非顶级区域?
▷🦆
在while循环中追踪r1和r2的父区域,如果r1或r2的某个父区域在字典`p`中没有映射,这种情况如何处理?
▷相关问题
二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点2
和节点8
的最近公共祖先是6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点2
和节点4
的最近公共祖先是2
, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出:3 解释:节点5
和节点1
的最近公共祖先是节点3 。
示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点5
和节点4
的最近公共祖先是节点5 。
因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1,2], p = 1, q = 2 输出:1
提示:
- 树中节点数目在范围
[2, 105]
内。 -109 <= Node.val <= 109
- 所有
Node.val
互不相同
。 p != q
p
和q
均存在于给定的二叉树中。