删除树节点
难度:
标签:
题目描述
代码结果
运行时间: 52 ms, 内存: 18.0 MB
/*
* Problem 1273: Delete Tree Nodes
* Given a tree represented by an integer array nodes, where nodes[i] is the value of the ith node.
* The tree has n nodes with node 0 as the root. The array parent of length n, where parent[i] is the parent of the ith node.
* Delete the subtrees of nodes with a value of 0 and return the number of remaining nodes.
*
* Approach using Java Streams:
* 1. Parse the parent array to construct the tree structure.
* 2. Use a depth-first search (DFS) to traverse the tree using streams.
* 3. Calculate the sum of subtree values and count nodes.
* 4. If the sum of a subtree is zero, exclude it from the count.
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int deleteTreeNodes(int nodes, int[] parent, int[] value) {
Map<Integer, List<Integer>> tree = IntStream.range(0, nodes).boxed()
.collect(Collectors.groupingBy(i -> parent[i]));
return dfs(0, tree, value)[1];
}
private int[] dfs(int node, Map<Integer, List<Integer>> tree, int[] value) {
int sum = value[node];
int count = 1;
if (tree.containsKey(node)) {
for (int child : tree.get(node)) {
int[] result = dfs(child, tree, value);
sum += result[0];
count += result[1];
}
}
if (sum == 0) {
count = 0;
}
return new int[]{sum, count};
}
}
解释
方法:
本题解采用拓扑排序的方法来解决删除树节点的问题。首先,计算每个节点的入度,然后使用一个队列来存储所有入度为0的节点(即叶子节点)。从这些叶子节点开始,逐步向上更新其父节点的节点值和节点数量。如果某个节点的值更新后为0,则该节点以及其所有子节点都不应被计算在内,因此将其节点数量设置为0。最终,队列中会处理每个节点,直到到达根节点。这种方法从底部叶子节点向上至根节点逐层剪枝,直到所有的节点都被处理过。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在解决删除树节点这个问题时,为什么选择使用拓扑排序而不是其他如深度优先搜索(DFS)或广度优先搜索(BFS)的方法?
▷🦆
如何处理树中某个节点的值更新为0之后,其对应的子节点是否也应该被考虑为删除或值为0?
▷🦆
在更新父节点的值和节点数量时,如果父节点的值变为0,是否还需要继续更新其父节点的值和节点数量?
▷🦆
代码中使用了队列来存储入度为0的节点,这种做法在实际执行中是如何保证从叶子节点逐层向上更新的?
▷