根到叶路径上的不足节点
难度:
标签:
题目描述
给你二叉树的根节点 root
和一个整数 limit
,请你同时删除树中所有 不足节点 ,并返回最终二叉树的根节点。
假如通过节点 node
的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit
,则该节点被称之为 不足节点 ,需要被删除。
叶子节点,就是没有子节点的节点。
示例 1:

输入:root = [1,2,3,4,-99,-99,7,8,9,-99,-99,12,13,-99,14], limit = 1 输出:[1,2,3,4,null,null,7,8,9,null,14]
示例 2:

输入:root = [5,4,8,11,null,17,4,7,1,null,null,5,3], limit = 22 输出:[5,4,8,11,null,17,4,7,null,null,null,5]
示例 3:

输入:root = [1,2,-3,-5,null,4,null], limit = -1 输出:[1,null,-3,4]
提示:
- 树中节点数目在范围
[1, 5000]
内 -105 <= Node.val <= 105
-109 <= limit <= 109
代码结果
运行时间: 41 ms, 内存: 17.6 MB
/*
* In this Java Stream solution, we cannot directly use streams to handle tree traversal due to their recursive nature.
* However, the logic remains similar, and we'll use traditional recursive methods but explain using Stream API concepts.
* This solution involves traversing the tree using a recursive function that calculates the maximum path sum from the root to any leaf.
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public TreeNode sufficientSubset(TreeNode root, int limit) {
return dfs(root, 0, limit);
}
private TreeNode dfs(TreeNode node, int sum, int limit) {
if (node == null) return null;
sum += node.val;
if (node.left == null && node.right == null) {
return sum < limit ? null : node;
}
node.left = dfs(node.left, sum, limit);
node.right = dfs(node.right, sum, limit);
return node.left == null && node.right == null ? null : node;
}
}
解释
方法:
这个题解使用了递归的方式处理每个节点,以判断是否保留或删除该节点。首先,每次递归调用都会从limit中减去当前节点的值,然后检查当前节点是否为叶子节点(即同时没有左右子节点)。对于叶子节点,如果剩余的limit值大于0,说明这条路径的总和不足,因此需要删除这个叶子节点。对于非叶子节点,递归地调用左右子节点,更新当前节点的左右子节点引用。最后,如果一个节点的左右子节点都被删除了,说明这个节点也变成了不足节点,因此也应该被删除。整个过程从根节点开始递归地处理,直到所有的不足节点都被删除。
时间复杂度:
O(n)
空间复杂度:
O(h),其中h是树的高度。在最坏的情况下,这可以达到O(n)。
代码细节讲解
🦆
递归函数中对剩余的limit进行减少时,为什么选择减去当前节点的值而不是其他数值?
▷🦆
在递归删除节点的过程中,如果某个节点的一个子节点被删除,但另一个子节点没有被删除,这种情况下该如何处理当前节点?
▷🦆
根据题目的逻辑,如果根节点自身就是一个不足节点,返回的结果会是什么?
▷🦆
递归调用的终结条件是什么?是否可能出现栈溢出的情况,特别是在处理极端不平衡的大树时?
▷