*leetcode-5109-最小公共区域-medium

题目描述

给你一些区域列表 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 个字母。

解题思路

这是13场双周赛的B题,知道是LCA,可是百度了还是不会做,我可能是个弱智

  • 讨论区看到的题解,代码简洁高效,绝活!
  • 这个题看起来难点就是在怎么构建这一课数,这里用数组来模拟,用了两个map来准确定位,很棒
  • LCA的思路很简单,知道深度就可以一直往上**x = TN[x].fa;**就行了
struct node {
    string data;
    int depth;
    int fa;
    vector<int> chi;
}TN[100001];
class Solution {
public:
    map<string, int> m;
    map<int, string> m2;
    int msize = 0;
    string findSmallestRegion(vector<vector<string>>& regions, string region1, string region2) {
        TN[1].depth = 0;
        TN[1].fa = 1;
        for (int i = 0; i < regions.size(); i++) {
            string a = regions[i][0];
            if (m[a] == 0) {
                msize++;
                m[a] = msize;
                m2[msize] = a;
            }
            TN[m[a]].data = regions[i][0];
            for (int j = 1; j < regions[i].size(); j++) {
                string b = regions[i][j];
                if (m[b] == 0) {
                    msize++;
                    m[b] = msize;
                    m2[msize] = b;
                }
                TN[m[b]].data = regions[i][j];
                TN[m[a]].chi.push_back(m[b]);
                TN[m[b]].fa = m[a];
                TN[m[b]].depth = TN[m[a]].depth + 1;
            }
        }
        int x = m[region1];
        int y = m[region2];
        while (TN[x].depth < TN[y].depth) {
            y = TN[y].fa;
        }
        while (TN[x].depth > TN[y].depth) {
            x = TN[x].fa;
        }
        while (1) {
            if (x == y) break;
            x = TN[x].fa;
            y = TN[y].fa;
        }
        return m2[x];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值