树的直径

leetcode1245. 树的直径

给你这棵「无向树」,请你测算并返回它的「直径」:这棵树上最长简单路径的 边数

我们用一个由所有「边」组成的数组 edges 来表示一棵无向树,其中 edges[i] = [u, v] 表示节点 u 和 v 之间的双向边。

树上的节点都已经用 {0, 1, ..., edges.length} 中的数做了标记,每个节点上的标记都是独一无二的。

  • 0 <= edges.length < 10^4
  • edges[i][0] != edges[i][1]
  • 0 <= edges[i][j] <= edges.length
  • edges 会形成一棵无向树

本题可以用两次BFS求出

第一次BFS:随机选择一个点,求出离这个点最远的点,记为p1,此为树的直径的一个端点

第二次BFS:以p1为起点进行BFS,求出离p1距离最远的点,记为p2,此为树的直径的另一个端点,两个点之间的距离就是树的直径

具体证明可以分情况讨论,下面只讨论一种情况,其他情况可以用相同方法讨论出

设树的直径的两个端点为P1,P2

我们以X为起点进行BFS,假设求出与X距离最远的点是Y,那么距离(X, Y) > 距离(X,P1),则距离(X, Y) + 距离(X, P2) > 距离(X,P1) + 距离(X, P2),此时出现了比树的直径更长的一条路径,与先前假设矛盾,所以以X为起点进行BFS必然可以到达树的直径的一个端点,最后从一个端点进行BFS就可以求出树的直径

class Solution:
    def treeDiameter(self, edges: List[List[int]]) -> int:
        if len(edges) == 0:
            return 0
        n = len(edges) + 1 # 点的数量
        g = defaultdict(list)
        for i in edges:
            g[i[0]].append(i[1])
            g[i[1]].append(i[0])

        # 1、获取距离随机选择的点最大距离的点
        q = deque()
        q.append(edges[0][0])
        used = set()
        while q:
            x = q.popleft()
            if x in used:
                continue
            if len(used) == n - 1:
                point = x
                break
            used.add(x)
            for i in g[x]:
                q.append(i)

        # 2、获取直径
        q = deque()
        q.append(point)
        used = set([point])
        res = -1
        while q:
            le = len(q)
            for _ in range(le):
                x = q.popleft()
                for i in g[x]:
                    if i not in used:
                        used.add(i)
                        q.append(i)
            res += 1
        return res

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值