可以被 K 整除连通块的最大数目
难度:
标签:
题目描述
There is an undirected tree with n
nodes labeled from 0
to n - 1
. You are given the integer n
and a 2D integer array edges
of length n - 1
, where edges[i] = [ai, bi]
indicates that there is an edge between nodes ai
and bi
in the tree.
You are also given a 0-indexed integer array values
of length n
, where values[i]
is the value associated with the ith
node, and an integer k
.
A valid split of the tree is obtained by removing any set of edges, possibly empty, from the tree such that the resulting components all have values that are divisible by k
, where the value of a connected component is the sum of the values of its nodes.
Return the maximum number of components in any valid split.
Example 1:

Input: n = 5, edges = [[0,2],[1,2],[1,3],[2,4]], values = [1,8,1,4,4], k = 6 Output: 2 Explanation: We remove the edge connecting node 1 with 2. The resulting split is valid because: - The value of the component containing nodes 1 and 3 is values[1] + values[3] = 12. - The value of the component containing nodes 0, 2, and 4 is values[0] + values[2] + values[4] = 6. It can be shown that no other valid split has more than 2 connected components.
Example 2:

Input: n = 7, edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values = [3,0,6,1,5,2,1], k = 3 Output: 3 Explanation: We remove the edge connecting node 0 with 2, and the edge connecting node 0 with 1. The resulting split is valid because: - The value of the component containing node 0 is values[0] = 3. - The value of the component containing nodes 2, 5, and 6 is values[2] + values[5] + values[6] = 9. - The value of the component containing nodes 1, 3, and 4 is values[1] + values[3] + values[4] = 6. It can be shown that no other valid split has more than 3 connected components.
Constraints:
1 <= n <= 3 * 104
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
values.length == n
0 <= values[i] <= 109
1 <= k <= 109
- Sum of
values
is divisible byk
. - The input is generated such that
edges
represents a valid tree.
代码结果
运行时间: 173 ms, 内存: 34.9 MB
/*
* 思路:
* 1. 使用DFS和Java Stream来计算每个节点的子树值和,并检查是否可以被k整除。
* 2. 对于能被k整除的子树,增加连通块数。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
public int maxKDivisibleComponents(int n, int[][] edges, int[] values, int k) {
// 构建图
Map<Integer, List<Integer>> graph = Arrays.stream(edges)
.flatMap(e -> Stream.of(Map.entry(e[0], e[1]), Map.entry(e[1], e[0])))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
int[] sum = new int[n];
int[] res = new int[1];
boolean[] visited = new boolean[n];
// 从根节点0开始DFS
dfs(0, graph, values, k, sum, visited, res);
return res[0];
}
private int dfs(int node, Map<Integer, List<Integer>> graph, int[] values, int k, int[] sum, boolean[] visited, int[] res) {
visited[node] = true;
sum[node] = values[node];
for (int neighbor : graph.getOrDefault(node, Collections.emptyList())) {
if (!visited[neighbor]) {
sum[node] += dfs(neighbor, graph, values, k, sum, visited, res);
}
}
// 如果子树和可以被k整除
if (sum[node] % k == 0) {
res[0]++;
return 0;
}
return sum[node];
}
}
解释
方法:
时间复杂度:
空间复杂度: