LeetCode 题解工作台

根到叶路径上的不足节点

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

category

3

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

中等 · 二分·树·traversal

bolt

答案摘要

我们递归遍历整棵树,对于当前遍历到的节点 : 如果 为空,那么返回空;否则,我们将 减去当前节点的值,即 $limit = limit - root.val$,然后继续执行下述步骤。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·树·traversal 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你二叉树的根节点 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

 

lightbulb

解题思路

方法一:递归

我们递归遍历整棵树,对于当前遍历到的节点 rootroot

如果 rootroot 为空,那么返回空;否则,我们将 limitlimit 减去当前节点的值,即 limit=limitroot.vallimit = limit - root.val,然后继续执行下述步骤。

如果 rootroot 为叶子节点(即 rootroot 的左右子节点都为空),说明我们已经走完了一条从根节点到叶子节点的路径。如果此时 limit>0limit \gt 0,说明该路径上所有节点的值的和小于 limitlimit,我们返回空节点,表示删除;否则,说明该路径上所有节点的值的和大于等于 limitlimit,我们返回 rootroot

如果 rootroot 不是叶子节点,那么我们递归调用函数 sufficientSubsetsufficientSubset,对 rootroot 的左右子节点分别进行处理,并将返回值分别赋值给 rootroot 的左右子节点。

如果 rootroot 的左右子节点在经过递归调用后变成了空节点,那么说明 rootroot 的左右子树中所有从根节点到叶子节点的路径上所有节点的值的和都小于 limitlimit,因此我们返回空节点,表示删除 rootroot;否则,说明 rootroot 的左右子树中存在从根节点到叶子节点上所有节点值的和大于等于 limitlimit 的路径,因此我们返回 rootroot

时间复杂度 O(n)O(n),空间复杂度 O(n)O(n)。其中 nn 是二叉树的节点个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sufficientSubset(
        self, root: Optional[TreeNode], limit: int
    ) -> Optional[TreeNode]:
        if root is None:
            return None
        limit -= root.val
        if root.left is None and root.right is None:
            return None if limit > 0 else root
        root.left = self.sufficientSubset(root.left, limit)
        root.right = self.sufficientSubset(root.right, limit)
        return None if root.left is None and root.right is None else root
speed

复杂度分析

指标
时间complexity is O(n) as each node is visited once during DFS. Space complexity is O(h), where h is the height of the tree, due to recursive call stack usage.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Ask about how the path sum is tracked efficiently during traversal.

  • question_mark

    Probe if deletion propagation from leaves to root is handled correctly.

  • question_mark

    Watch for handling negative node values or limits and null children.

warning

常见陷阱

外企场景
  • error

    Forgetting to propagate node deletion upwards when all children are insufficient.

  • error

    Incorrectly computing path sums at non-leaf nodes instead of full root-to-leaf paths.

  • error

    Ignoring edge cases like negative node values or limits, leading to wrong pruning.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Prune nodes where the maximum root-to-leaf path sum is below limit instead of every path.

  • arrow_right_alt

    Return the count of nodes deleted rather than the pruned tree.

  • arrow_right_alt

    Modify the tree in place without creating new nodes to save memory.

help

常见问题

外企场景

根到叶路径上的不足节点题解:二分·树·traversal | LeetCode #1080 中等