【算法】Tree Diameter 树的直径

1245. Tree Diameter 树的直径

如果不懂DFS,BFS,和递归方面的内容,下面就可以不用看了。

树上任意两节点之间最长的简单路径即为树的「直径」

在此不做证明,只说方法,具体证明过程可以百度。

方法很简单,

  • 找一个节点A,从A出发到距离A最远的节点B,
  • 然后从节点B出发,找到距离节点B最远的节点C。然后 B → C B\rightarrow C BC就是这个树中最远的距离,也称为树的直径,即这个路径上边的数量

这个结论是 对 M叉树

简单来说,分为2步,每一步都是找距离当前节点最远的一个节点。这个可以使用BFS,也可以使用DFS处理。

当然也可以使用树形DP来处理。

当节点 v v v 的处于最长的路径上,这个最长的路径 L L L 可能的组成就有几个情况。

  1. V V V为 root向下 的最长的2个路径【这2个路径不能有公共边】 组成。

  2. V V V 在路径上,并且 从 V V V向下的最长路径,一定是这个L的组成部分。

定义节点的编号 0 → n − 1 0\rightarrow n-1 0n1,一共n个节点。

定义一个 d f s ( u , f a ) dfs( u, fa) dfs(u,fa) u 表示当前的节点, fa 表示其 父节点【也可以认为是从fa节点遍历过来到达u】。

同时为了记录u的最长的2个路径,定义 d 1 [ n ] , d 2 [ n ] d1[n],d2[n] d1[n],d2[n]分别表示从 u出发的最长路径 d 1 [ u ] d1[u] d1[u],和 次长路径 d 2 [ u ] d2[u] d2[u].

时间复杂度是 O ( N ) O(N) O(N),空间复杂度是 O ( N ) O(N) O(N)

int res = 0;
    public List<Integer>[] map;
    public int[] d1,d2;
    public int treeDiameter(int[][] edges) {
        map = new ArrayList[edges.length+1];
        for(int i=0 ; i<map.length ; i++){
            map[i] = new ArrayList<>();
        }
        int n = map.length;
        d1 = new int[n];
        d2 = new int[n];

        for(int[] edge : edges){
            map[edge[0]].add(edge[1]);
            map[edge[1]].add(edge[0]);
        } 
        dfs(0,-1); 
        return res;
    } 
    
    public void dfs(int u,int fa){ 
        List<Integer> list = map[u];
        d1[u]= d2[u] =0; 
        for(int next : list){
            if(next== fa) continue;
            dfs(next,u);
            int t = d1[next]+1;
            if(t>d1[u]){
                d2[u] = d1[u];
                d1[u] = t; 
            } else if(t>d2[u]){
                d2[u] =t;
            }
        }
        res = Math.max(res,d2[u]+d1[u]); 
        return  ; 
    }

Tag

DP,树形DP

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eric.Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值