
java solution
java
class Solution {
public TreeNode pruneTree(TreeNode root) {
//递归后序遍历来解决此题
if(root == null) return null;
//先剪枝左右子树
root.left = pruneTree(root.left);
root.right = pruneTree(root.right);
//然后处理当前节点
if(root.val == 0 && root.left == null && root.right == null) {
return null;
}
//否则,保留当前节点
return root;
}
}
这部分代码片段,为什么判断条件不是 root.val == 0 && root.left.val == 0 && root.right.val == 0
if (root.val == 0 && root.left == null && root.right == null) {
return null;
}
root.left == null
和 root.right == null
的判断是 判断子树是否已经被剪掉(即不存在),而不是判断子节点的值是否为 0。
👇 详细解释如下:
❌ root.left == 0 && root.right == 0
------ 错误的写法
root.left
和root.right
是TreeNode
类型,不是整数,不能直接用== 0
比较。- 即使你访问的是值(比如
root.left.val == 0
),也不够,因为:- 即使
val == 0
,只判断这一层还不够,整个子树里也可能包含 1,那这个子树就不能剪掉。
- 即使
✅ root.left == null && root.right == null
------ 正确的做法
- 表示 当前节点的左子树和右子树都已经被递归剪掉了(要么原本是空的,要么在递归过程中被剪为 null)。
- 然后再判断当前节点的值:
- 如果是
0
,那么这个节点及其所有后代都不包含1
,就应该被剪掉,返回null
。 - 如果是
1
,即使左右子树都为空,也要保留这个节点。
- 如果是
🔄 递归的核心思想:
在后序遍历中,我们是先把左子树和右子树递归"剪干净"后,才处理当前节点。
所以:
java
root.left = pruneTree(root.left);
root.right = pruneTree(root.right);
之后,root.left
和 root.right
已经是处理完的结果 ------ 如果某一子树里没有 1,它就已经是 null
。
这时候判断:
java
if (root.val == 0 && root.left == null && root.right == null)
意味着:
当前节点是 0,并且它的子树中没有 1 ------ 满足"整棵子树没有 1"的条件,因此需要剪掉。