leetcode
leetcode 1001 ~ 1050
最小公共区域

最小公共区域

难度:

标签:

题目描述

代码结果

运行时间: 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`时,对于包含多个子区域的列表项,如何确保字典正确反映了所有子区域到父区域的映射?
在代码中,使用了一个字典推导式`{i: j for j, *r in regions for i in r}`来构建父区域字典。这种写法利用了Python的解包特性,其中`j`是每个列表的第一个元素,代表父区域,而`*r`是剩余的元素,代表所有子区域。字典推导式中的`for i in r`确保了每个子区域`i`都会被映射到其对应的父区域`j`。因此,这种方法能够确保即使父区域有多个子区域,字典也能正确地映射每个子区域到其父区域。
🦆
代码中没有显式地处理r1或r2为顶级区域的情况,这是否意味着算法假设输入的r1和r2总是非顶级区域?
代码确实没有显式处理r1或r2为顶级区域的情况。在这个算法中,如果r1或r2是顶级区域,它们将不会在字典`p`中作为键出现,因此`while r1 in p`或`while r2 in p`的循环将不会执行。这意味着,如果r1或r2是顶级区域,它们将直接被视为潜在的最小公共区域。因此,可以认为是有一个隐含的假设,即r1和r2通常不是顶级区域,否则算法会直接返回顶级区域本身作为结果。
🦆
在while循环中追踪r1和r2的父区域,如果r1或r2的某个父区域在字典`p`中没有映射,这种情况如何处理?
如果在追踪过程中,r1或r2的某个父区域在字典`p`中没有映射,意味着已经到达了顶级区域,因为顶级区域没有更高的父区域。在代码中,一旦`r1`或`r2`不在字典`p`中,相应的循环就会结束。对于r2,如果在它的追踪过程中未找到与r1共同的区域,最终它会返回当前的r2值,可能是顶级区域。这种处理方式暗示了到达顶级区域后,没有更高的父区域可以追踪,因此返回当前的区域作为最小公共区域。

相关问题

二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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
  • pq 均存在于给定的二叉树中。