目录
🌲 LeetCode 好叶子节点对的数量(Python详解)
🌲 LeetCode 好叶子节点对的数量(Python详解)
📘 题目描述
给你一棵二叉树的根节点 root
和一个整数 distance
。
如果二叉树中两个 叶子节点 之间的最短路径长度 小于或等于 distance
,那么这两个叶子节点可以构成一组 "好叶子节点对"。
请你返回 二叉树中好叶子节点对的数量。
🎯 示例
输入:
root = [1,2,3,null,4]
distance = 3
输出:
1
解释:
树结构如下:
1
/ \
2 3
\
4
- 叶子节点为
4
和3
。 4
到3
的最短路径是:4 → 2 → 1 → 3
,共 3 条边。- 因为路径长度等于
distance=3
,所以是一组好叶子节点对。
📈 解题分析
目标:
统计所有满足条件的叶子节点对(两两之间的路径长度不超过 distance)。
注意点:
- “路径长度” 指的是节点之间边的数量,而不是节点数量。
- 要求 遍历所有叶节点对,并统计符合条件的对数。
- 暴力法会超时,因此需要 自底向上的深度优先搜索(DFS) + 剪枝。
🧠 解题思路
我们使用 DFS 递归的方法来遍历二叉树,并在每个节点向上返回它子树中所有叶节点到当前节点的路径长度(以数组形式记录)。
关键步骤:
- 定义返回值:
-
- 每个节点向上传递一个数组
dist
,其中dist[i]
表示从当前节点出发距离为i+1
的叶子节点数量。
- 每个节点向上传递一个数组
- 统计好叶子对:
-
- 对于当前节点,组合左右子树返回的
dist
数组:
- 对于当前节点,组合左右子树返回的
-
-
- 遍历
left[i]
与right[j]
: - 若
i + j + 2 <= distance
(+2 是因为路径从左子树叶到右子树叶要经过当前节点的两个边),则这是一组好叶子节点对。
- 遍历
-
- 构造合并后的数组向上传递:
-
- 将左右子树中所有叶节点的距离加一(因为当前节点到它们的距离多了一层)。
- 超出
distance
的距离可剪枝。
🔧 代码实现(Python)
# 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 countPairs(self, root: Optional[TreeNode], distance: int) -> int:
self.ans = 0
def dfs(node):
if not node:
return [0] * distance
if not node.left and not node.right:
dist = [0] * distance
dist[0] = 1
return dist
left = dfs(node.left)
right = dfs(node.right)
# 统计左右子树之间的好叶子节点对
for i in range(distance):
for j in range(distance):
if i + j + 2 <= distance:
self.ans += left[i] * right[j]
# 构建向上传递的距离数组
merged = [0] * distance
for i in range(distance - 1):
merged[i + 1] = left[i] + right[i]
return merged
dfs(root)
return self.ans
📊 分析与比较
方法 | 时间复杂度 | 空间复杂度 | 是否超时 | 可读性 |
暴力法 | O(n²)(枚举所有叶子节点对) | O(n) | 会超时 | 简单但低效 |
DFS + 剪枝(当前方法) | O(n * d²)(每个节点比较 d² 次) | O(d) | ✅ 不超时 | ✅ 高效且直观 |
说明:
n
是二叉树中的节点数。d
是distance
的值(最大为10,根据题目约束)。- 由于
distance
很小,d²
是常量,因此 DFS 方法在实际中表现优异。
🧪 更多示例
示例 2:
root = [1]
distance = 1
输出:0
说明: 只有一个节点,无叶子对。
示例 3:
root = [1,2,3,4,5,null,6]
distance = 3
树结构如下:
1
/ \
2 3
/ \ \
4 5 6
叶子节点为:[4, 5, 6]。满足条件的对有:
- 4 & 5:路径为 4→2→5,距离2
- 5 & 6:路径为 5→2→1→3→6,距离4(不满足)
- 4 & 6:路径为 4→2→1→3→6,距离4(不满足)
输出:1
✨ 总结
本题考查的是树的递归遍历与路径问题。通过深度优先搜索,我们可以有效地自底向上收集叶子节点的距离信息,并在遍历过程中完成对符合条件的叶子节点对的统计。
🔑 技巧回顾:
- 自底向上的 DFS 可用于统计叶子到当前节点的路径。
- 利用数组
dist
优雅处理距离分布。 - 注意剪枝:数组只保留到
distance
的信息,防止爆炸式递归。