题目大意:
删除树节点
给你一棵以节点 0 为根节点的树,定义如下:
- 节点的总数为 nodes 个
- 第 i 个节点的值为 value[i]
- 第 i 个节点的父节点是 parent[i]
请你删除节点值之和为 0 的每一棵子树。
在完成所有删除之后,返回树中剩余节点的数目。
示例1:
输入: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-1] 输出: 2
提示:
- 1 <= nodes <= 10^4
- -10^5 <= value[i] <= 10^5
- parent.length == nodes
- parent[0] == -1 表示节点 0 是树的根。
如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=1273
解题思路分析:
本题需要先对节点进行整理,题目给出了每个节点的父节点,这不利于做题,因此我们需要统计出每个节点的子节点有哪些。
统计出子节点信息后,我们使用递归方式从根节点开始查看每个节点下(包含当前节点)所有节点的和,如果当前节点(当前子树)下所有节点和为0,那么,可将当前节点下的子节点清空(相当于删除节点操作),同时当前节点值变为0。递归结束时,总和为0的子树子节点都会被删除,注意子树的根节点没被删除,只是值变为0而已。
节点删除操作结束之后,我们就可以统计剩下的节点数量,还是使用递归,从根节点开始递归统计每个节点下子节点的数量,如果当前节点为叶子节点,当值为0时,返回0,非0时,返回个数1。
实现代码:
List<Integer>[] children; // 每个节点的子节点
public int deleteTreeNodes(int nodes, int[] parent, int[] value) {
children = new List[nodes];
for(int i=0;i<nodes;i++){
children[i]=new ArrayList<>();
}
// 统计每个节点的子节点
for(int i=0;i<nodes;i++){
int root=parent[i];
if(root==-1) continue;
children[root].add(i);
}
// 删除和为0的子树
helper(value, parent, 0);
// 统计删除后剩余节点数量,返回。
return count(0, value);
}
int helper(int[] value, int[] parent, int index){
int sum=value[index];
for(int child : children[index]){
sum+=helper(value, parent, child);
}
if(sum==0){
children[index].clear();
value[index]=0;
}
return sum;
}
int count(int index, int[] value){
if(children[index].size()==0){
return value[index]==0 ? 0:1;
}
int count=1;
for(int child : children[index]){
count+=count(child, value);
}
return count;
} 本题解法执行时间为13ms。
Runtime: 13 ms, faster than 60.57% of Java online submissions for Delete Tree Nodes.
Memory Usage: 40.5 MB, less than 100.00% of Java online submissions for Delete Tree Nodes.
本网站文章均为原创内容,并可随意转载,但请标明本文链接如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: http://leetcode.jp/leetcode-1273-delete-tree-nodes-解题思路分析/