2025-02-11:合并两棵树后的最小直径。用go语言,给定两棵无向树,第一棵树有 n 个节点,第二棵树有 m 个节点,节点编

举报
福大大架构师每日一题 发表于 2025/02/11 21:13:24 2025/02/11
【摘要】 2025-02-11:合并两棵树后的最小直径。用go语言,给定两棵无向树,第一棵树有 n 个节点,第二棵树有 m 个节点,节点编号分别为 0 到 n-1 和 0 到 m-1。每棵树的边信息通过二维数组 edges1 和 edges2 表示,其中 edges1[i] = [ai, bi] 表示第一棵树中节点 ai 和 bi 之间存在一条边,而 edges2[i] = [ui, vi] 则表示第...

2025-02-11:合并两棵树后的最小直径。用go语言,给定两棵无向树,第一棵树有 n 个节点,第二棵树有 m 个节点,节点编号分别为 0 到 n-1 和 0 到 m-1。每棵树的边信息通过二维数组 edges1 和 edges2 表示,其中 edges1[i] = [ai, bi] 表示第一棵树中节点 ai 和 bi 之间存在一条边,而 edges2[i] = [ui, vi] 则表示第二棵树中节点 ui 和 vi 之间有一条边。

你的任务是从每棵树中选择一个节点,并通过一条新边将这两个节点连接起来。最终,你需要返回添加这条边之后新形成的树的最小直径。

在此,树的直径定义为任意两个节点之间的最长路径长度。

1 <= n, m <= 100000。

edges1.length == n - 1。

edges2.length == m - 1。

edges1[i].length == edges2[i].length == 2。

edges1[i] = [ai, bi]。

0 <= ai, bi < n。

edges2[i] = [ui, vi]。

0 <= ui, vi < m。

输入保证 edges1 和 edges2 分别表示一棵合法的树。

输入:edges1 = [[0,1],[0,2],[0,3]], edges2 = [[0,1]]。

输出:3。

解释:

将第一棵树中的节点 0 与第二棵树中的任意节点连接,得到一棵直径为 3 的树。

答案2025-02-11:

chatgpt

题目来自leetcode3203。

大体步骤如下:

1.定义一个函数 diameter 用于计算树的直径。首先,构建两个邻接表 g 分别存储两棵树的边关系。然后定义一个递归内部函数 dfs 用于进行深度优先搜索(DFS)。

2.在 dfs 函数中,通过递归遍历树的节点,计算每个非父节点到根节点的最长路径。在遍历过程中更新直径的长度。

3.计算第一棵树和第二棵树的直径分别为 d1d2

4.计算合并后树的直径:

  • 如果将两棵树通过一条边直接相连,直径为两棵树直径的最大值。

  • 否则,考虑通过一个节点连接两棵树,直径为 (d1+1)/2 + (d2+1)/2 + 1

5.输出返回合并后树的最小直径。

总的时间复杂度:

  • 构建邻接表:O(n + m),其中 n 和 m 分别代表两棵树的节点数目。

  • 计算两棵树的直径:O(n + m)。

  • 计算合并后树的直径:O(1)。

总的额外空间复杂度:

  • 邻接表存储:O(n + m)。

  • 递归调用栈:O(n + m)。

Go完整代码如下:

package main

import (
	"fmt"
)

func diameter(edges [][]int) (res int) {
	g := make([][]int, len(edges)+1)
	for _, e := range edges {
		x, y := e[0], e[1]
		g[x] = append(g[x], y)
		g[y] = append(g[y], x)
	}
	var dfs func(int, int) int
	dfs = func(x, fa int) (maxLen int) {
		for _, y := range g[x] {
			if y != fa {
				subLen := dfs(y, x) + 1
				res = max(res, maxLen+subLen)
				maxLen = max(maxLen, subLen)
			}
		}
		return
	}
	dfs(0, -1)
	return
}

func minimumDiameterAfterMerge(edges1, edges2 [][]int) int {
	d1 := diameter(edges1)
	d2 := diameter(edges2)
	return max(d1, d2, (d1+1)/2+(d2+1)/2+1)
}

func main() {
	edges1 := [][]int{{0, 1}, {0, 2}, {0, 3}}
	edges2 := [][]int{{0, 1}}
	result := minimumDiameterAfterMerge(edges1, edges2)
	fmt.Println(result)
}

在这里插入图片描述

Rust完整代码如下:

use std::cmp;

fn diameter(edges: Vec<Vec<i32>>) -> i32 {
    let n = edges.len() + 1;
    let mut g = vec![Vec::new(); n];
    
    for edge in edges {
        let x = edge[0];
        let y = edge[1];
        g[x as usize].push(y);
        g[y as usize].push(x);
    }

    let mut res = 0;

    fn dfs(x: i32, fa: i32, g: &Vec<Vec<i32>>, res: &mut i32) -> i32 {
        let mut max_len = 0;
        for &y in &g[x as usize] {
            if y != fa {
                let sub_len = dfs(y, x, g, res) + 1;
                *res = cmp::max(*res, max_len + sub_len);
                max_len = cmp::max(max_len, sub_len);
            }
        }
        max_len
    }

    dfs(0, -1, &g, &mut res);
    res
}

fn minimum_diameter_after_merge(edges1: Vec<Vec<i32>>, edges2: Vec<Vec<i32>>) -> i32 {
    let d1 = diameter(edges1);
    let d2 = diameter(edges2);
    cmp::max(d1, cmp::max(d2, (d1 + 1) / 2 + (d2 + 1) / 2 + 1))
}

fn main() {
    let edges1 = vec![vec![0, 1], vec![0, 2], vec![0, 3]];
    let edges2 = vec![vec![0, 1]];
    let result = minimum_diameter_after_merge(edges1, edges2);
    println!("{}", result);
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def diameter(edges):
    n = len(edges) + 1
    g = [[] for _ in range(n)]
    
    for x, y in edges:
        g[x].append(y)
        g[y].append(x)
    
    res = 0

    def dfs(x, fa):
        nonlocal res
        max_len = 0
        for y in g[x]:
            if y != fa:
                sub_len = dfs(y, x) + 1
                res = max(res, max_len + sub_len)
                max_len = max(max_len, sub_len)
        return max_len

    dfs(0, -1)
    return res

def minimum_diameter_after_merge(edges1, edges2):
    d1 = diameter(edges1)
    d2 = diameter(edges2)
    return max(d1, d2, (d1 + 1) // 2 + (d2 + 1) // 2 + 1)

if __name__ == "__main__":
    edges1 = [[0, 1], [0, 2], [0, 3]]
    edges2 = [[0, 1]]
    result = minimum_diameter_after_merge(edges1, edges2)
    print(result)

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。