牛客NC99 多叉树的直径【较难 深度优先 Java/Go/PHP】

题目

在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/a77b4f3d84bf4a7891519ffee9376df3

思路

核心就是树的最大直径(globalMax)一定是以某一个node为root最长的两个path-to-leaf.
就是普通dfs的同时算路径长度。

时间: O(n), DFS一次
空间: O(n)

参考答案Java

import java.util.*;

/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 树的直径
     * @param n int整型 树的节点个数
     * @param Tree_edge Interval类一维数组 树的边
     * @param Edge_value int整型一维数组 边的权值
     * @return int整型
     */
    public int solve (int n, Interval[] Tree_edge, int[] Edge_value) {
        //核心就是树的最大直径(globalMax)一定是以某一个node为root最长的两个path-to-leaf.
        //就是普通dfs的同时算路径长度。
        //
        //时间: O(n), DFS一次
        //空间: O(n)
        // node_id -> { {nei1, cost1}, {nei2, cost2}, ... }
        Map<Integer, List<int[]>> graph = new HashMap<>();
        int[] globalMax = {0};
        // construct graph
        for (int i = 0; i < n ; i++) {
            graph.put(i, new ArrayList<int[]>());
        }

        for (int i = 0; i < n - 1 ; i++) {
            // treat tree edge as bi-directional
            int from = Tree_edge[i].start;
            int to = Tree_edge[i].end;

            graph.get(from).add(new int[] {to, Edge_value[i]});
            graph.get(to).add(new int[] {from, Edge_value[i]});
        }

        // 因为edge是bi-directional, 随便从哪个node开始dfs都一样。这里用了node-0.
        // -1 作为parent
        dfs(graph, globalMax, 0, -1);
        return globalMax[0];
    }
    // returns the max cost path-to-leaf from this root.
    public int dfs(Map<Integer, List<int[]>> graph, int[] ans, int root,
                   int parent) {
        int maxCost = 0;
        int maxCost2 = 0;
        for (int[] nexts : graph.get(root)) {
            // NOTE: BaseCase (i.e. leaf) has only 1 nei, which is the parent
            //       thus leaf will return maxCost = 0 directly.
            if (nexts[0] == parent) continue;

            // recursively finds the max cost path to any leaf
            int cost = dfs(graph, ans, nexts[0], root) + nexts[1];
            // keep 2 largest cost
            if (cost >= maxCost) {
                maxCost2 = maxCost;
                maxCost = cost;
            } else if(cost >=maxCost2){
                maxCost2 = cost;
            }
        }

        // check if the 2 largest path is the global max
        int curcost = maxCost + maxCost2;
        if (curcost > ans[0]) {
            ans[0] = curcost;
        }

        return maxCost;
    }
}

参考答案Go

package main

import . "nc_tools"

/*
 * type Interval struct {
 *   Start int
 *   End int
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 树的直径
 * @param n int整型 树的节点个数
 * @param Tree_edge Interval类一维数组 树的边
 * @param Edge_value int整型一维数组 边的权值
 * @return int整型
 */
func solve(n int, Tree_edge []*Interval, Edge_value []int) int {
	//核心就是树的最大直径(globalMax)一定是以某一个node为root最长的两个path-to-leaf.
	//就是普通dfs的同时算路径长度。
	//
	//时间: O(n), DFS一次
	//空间: O(n)
	// node_id -> { {nei1, cost1}, {nei2, cost2}, ... }
	graph := map[int][]*Node{} //map表示图
	// construct graph
	for i := 0; i < n; i++ {
		graph[i] = []*Node{}
	}
	for i := 0; i < n-1; i++ {
		// treat tree edge as bi-directional
		from := Tree_edge[i].Start
		to := Tree_edge[i].End

		graph[from] = append(graph[from], &Node{to, Edge_value[i]})
		graph[to] = append(graph[to], &Node{from, Edge_value[i]})
	}
	// 因为edge是bi-directional, 随便从哪个node开始dfs都一样。这里用了node-0.
	// -1 作为parent
	ans := []int{0}
	dfs(graph, &ans, 0, -1)
	return ans[0]
}

func dfs(graph map[int][]*Node, ans *[]int, root, parent int) int {
	maxCost := 0
	maxCost2 := 0
	for _, nexts := range graph[root] {
		// NOTE: BaseCase (i.e. leaf) has only 1 nei, which is the parent
		//       thus leaf will return maxCost = 0 directly.
		if nexts.to == parent {
			continue
		}
		// recursively finds the max cost path to any leaf
		cost := dfs(graph, ans, nexts.to, root) + nexts.cost
		// keep 2 largest cost
		if cost >= maxCost {
			maxCost2 = maxCost
			maxCost = cost
		} else if cost >= maxCost2 {
			maxCost2 = cost
		}

	}
	// check if the 2 largest path is the global max
	cursot := maxCost + maxCost2
	if cursot > (*ans)[0] {
		(*ans)[0] = cursot
	}

	return maxCost
}

type Node struct {
	to   int
	cost int
}

参考答案PHP

<?php

/*class Interval{
    var $start = 0;
    var $end = 0;
    function __construct($a, $b){
        $this->start = $a;
        $this->end = $b;
    }
}*/

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 树的直径
 * @param n int整型 树的节点个数
 * @param Tree_edge Interval类一维数组 树的边
 * @param Edge_value int整型一维数组 边的权值
 * @return int整型
 */
function solve( $n ,  $Tree_edge ,  $Edge_value )
{
       //核心就是树的最大直径(globalMax)一定是以某一个node为root最长的两个path-to-leaf.
    //就是普通dfs的同时算路径长度。
    //
    //时间: O(n), DFS一次
    //空间: O(n)
    // node_id -> { {nei1, cost1}, {nei2, cost2}, ... }

    $graph = [];
    for($i=0;$i<$n;$i++){
        $graph[$i] = [];
    }
    // construct graph
    for($i=0;$i<$n-1;$i++){
        $from = $Tree_edge[$i]->start;
        $to = $Tree_edge[$i]->end;
        $graph[$from][count($graph[$from])] = [$to,$Edge_value[$i]];
        $graph[$to][count($graph[$to])] = [$from,$Edge_value[$i]];

    }

    $ans = [0];
    // 因为edge是bi-directional, 随便从哪个node开始dfs都一样。这里用了node-0.
    // -1 作为parent
    dfs($graph,$ans,0,-1);
    return $ans[0];
}

// returns the max cost path-to-leaf from this root.
function dfs($graph,&$ans,$root,$parent){
    $max1 =0;

    $max2 = 0;

    foreach ($graph[$root] as $nexts) {
        // NOTE: BaseCase (i.e. leaf) has only 1 nei, which is the parent
        //       thus leaf will return maxCost = 0 directly.
        if($nexts[0] == $parent) continue; //不走回头路
        // recursively finds the max cost path to any leaf
        $cost = dfs($graph,$ans,$nexts[0],$root)+$nexts[1];
        // keep 2 largest cost
        if($cost >= $max1){
            $max2=$max1;
            $max1 = $cost;
        }else if($cost >=$max2){
            $max2 = $cost;
        }
    }
    // check if the 2 largest path is the global max
    $curcost = $max1+$max2;
    if($curcost > $ans[0]){
        $ans[0] = $curcost;
    }
    return $max1;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

赵长辉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值