题目描述
有两棵 无向树
,分别有 n
和 m
个树节点。两棵树中的节点编号分别为 [0, n - 1]
和 [0, m - 1]
中的整数。
给你两个二维整数 edges1
和 edges2
,长度分别为 n - 1
和 m - 1
,其中 edges1[i] = [ai, bi]
表示第一棵树中节点 ai
和 bi
之间有一条边,edges2[i] = [ui, vi]
表示第二棵树中节点 ui
和 vi
之间有一条边。同时给你一个整数 k
。如果节点 u
和节点 v
之间路径的边数小于等于 k
,那么我们称节点 u
是节点 v
的 目标节点
。一个节点一定是它自己的 目标节点
。
请你返回一个长度为 n
的整数数组 answer
,answer[i]
表示将第一棵树中的一个节点与第二棵树中的一个节点连接一条边后,第一棵树中节点 i
的目标节点数目的最大值 。
注意:每个查询相互独立。意味着进行下一次查询之前,你需要先把刚添加的边给删掉。
示例 1:
输入:
edges1 = [[0, 1], [0, 2], [2, 3], [2, 4]], edges2 = [[0, 1], [0, 2], [0, 3], [2, 7], [1, 4], [4, 5], [4, 6]]
,k = 2
输出:[9, 7, 9, 8, 8]
解释:
- 对于
i = 0
,连接第一棵树中的节点 0 和第二棵树中的节点 0 。- 对于
i = 1
,连接第一棵树中的节点 1 和第二棵树中的节点 0 。- 对于
i = 2
,连接第一棵树中的节点 2 和第二棵树中的节点 4 。- 对于
i = 3
,连接第一棵树中的节点 3 和第二棵树中的节点 4 。- 对于
i = 4
,连接第一棵树中的节点 4 和第二棵树中的节点 4 。

示例 2:
输入:
edges1 = [[0, 1], [0, 2], [0, 3], [0, 4]], edges2 = [[0, 1], [1, 2], [2, 3]]
,k = 1
输出:[6, 3, 3, 3, 3]
解释:对于每个i
,连接第一棵树中的节点i
和第二棵树中的任意一个节点。

提示:
2 <= n, m <= 1000
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
都表示合法的树。 0 <= k <= 1000
思路分析
- 第一棵树内部目标节点计算:对于第一棵树中的每个节点
i
,计算在不添加新边的情况下,距离i
不超过k
的节点数(包括自身)。这部分节点不受添加边的影响,因为新边连接的是另一棵树。 - 第二棵树内部目标节点计算:对于第二棵树中的每个节点
j
,计算距离j
不超过k-1
的节点数(包括自身)。这是因为添加边后,从第一棵树节点i
到第二棵树节点v
的路径为i → a → b → v
,其中a
和b
是添加边的两个端点,路径长度为d1(i, a) + 1 + d2(b, v)
。为最大化第二棵树部分的贡献,选择a = i
(即连接点选在i
),这样路径长度简化为1 + d2(b, v)
。因此,第二棵树部分最多贡献距离b
不超过k-1
的节点数。 - 最大化第二棵树贡献:取第二棵树中所有节点在距离
k-1
内节点数的最大值maxCount2
。 - 合并结果:对于第一棵树中的每个节点
i
,其目标节点最大值为count1[i] + maxCount2
,其中count1[i]
是第一棵树内部距离i
不超过k
的节点数。
1 | public int[] maxTargetNodes(int[][] edges1, int[][] edges2, int k) { |
复杂度分析
- 时间复杂度:
O(n² + m²)
,其中n
和m
分别是两棵树的节点数。计算count1
和count2
时,对每个节点进行 BFS,每次 BFS 最坏O(n)
或O(m)
,总时间复杂度为O(n²)
和O(m²)
。 - 空间复杂度:
O(n + m)
,用于存储树的邻接表O(n + m)
和 BFS 的队列及访问标记O(n)
或O(m)
。