leetcode 310. 最小高度树

310. 最小高度树

一、题目

原题链接:310. 最小高度树

1.题目描述

树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。

给你一棵包含 n 个节点的树,标记为 0n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表(每一个边都是一对标签),其中 edges[i] = [ai, bi] 表示树中节点 aibi 之间存在一条无向边。

可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树

请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。

树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。

示例 1:

img

输入:n = 4, edges = [[1,0],[1,2],[1,3]]
输出:[1]
解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。

示例 2:

img

输入:n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
输出:[3,4]

提示:

  • 1 <= n <= 2 * 10^4
  • edges.length == n - 1
  • 0 <= ai, bi < n
  • ai != bi
  • 所有 (ai, bi) 互不相同
  • 给定的输入 保证 是一棵树,并且 不会有重复的边

2.基础框架

C++基础框架代码如下:

vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
}

3.解题思路

  • 题目分析
  1. 题目目标返回所有最小高度树的根节点。

  2. 树的高度定义:根节点和叶子结点之间的最长路径 边的数量。

  3. 最小高度树就是 最长的路径的中点作为根节点的树。

  4. 最长路径可以通过BFS求得。

  5. 如果最长路径长度为奇数,则最小高度树的根节点只有一个,如果为偶数,则最小高度树的根节点有两个。

  • 实现代码:

    #define N 20005
    vector<int> Edge[N];
    int pre[N];
    int dist[N];
    class Solution {
    public:
        void add_Edge(int u, int v)
        {
            Edge[u].push_back(v);
            Edge[v].push_back(u);
            return ;
        }
        void init(int n, vector<vector<int> >& edges)
        {
            
            for (int i = 0; i < n; i++)
                Edge[i].clear();
            return ;
        }
        
        int bfs(int u, int n)
        {
            memset(dist, -1, sizeof(dist));
            queue<int> que;
            que.push(u);
            dist[u] = 0;
            pre[u] = -1;
            while (!que.empty())
            {
                int u = que.front();
                que.pop();
                for (int i = 0; i < Edge[u].size(); i++)
                {
                    int v = Edge[u][i];
                    if (dist[v] == -1)
                    {
                        dist[v] = dist[u] + 1;
                        pre[v] = u;
                        que.push(v);
                    }
                }
            }
            int max1 = 0;
            for (int i = 1; i < n; i++)
            {
                if (dist[i] > dist[max1])
                    max1 = i;
            }
            return max1;
        }
        vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
            if (n == 1) return {0};
            init(n, edges);
            for (int i = 0; i < edges.size(); i++)
            {
                add_Edge(edges[i][0], edges[i][1]);
            }
            int x = bfs(edges[0][0], n);
            int y = bfs(x, n);
            // cout << x << " " << y << endl;
            vector<int> path;
            path.clear();
            while (x != y)
            {
                path.push_back(y);
                y = pre[y];
            }
            path.push_back(x);
            // for (auto i : path)
            //     cout << i << endl;
            if (path.size() & 1)
                return {path[(path.size() - 1) / 2]};
            else
                return {path[(path.size() - 1) / 2], path[path.size() / 2]};
        }
    };
    

二、参考资料

https://blog.csdn.net/WhereIsHeroFrom/article/details/124004342

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值