Article / 文章
LeetCode 第366题:寻找二叉树的叶子节点
给你一棵二叉树,请按以下方式收集它的叶子节点: 1. 收集所有叶子节点 2. 删除所有叶子节点 3. 重复这个过程直到树为空
📖 文章摘要
本文详细解析LeetCode第366题“寻找二叉树的叶子节点”,这是一道二叉树和深度优先搜索问题。文章提供了基于DFS的解法,包含C#、Python、C++三种语言实现,配有详细的算法分析和性能对比。适合想要提升二叉树处理能力的读者。
核心知识点: 二叉树、深度优先搜索、递归、层序遍历 难度等级: 中等 推荐人群: 具有基础算法知识,想要提升二叉树处理能力的程序员
题目描述
给你一棵二叉树,请按以下方式收集它的叶子节点:
- 收集所有叶子节点
- 删除所有叶子节点
- 重复这个过程直到树为空
示例
示例 1:
输入:[1,2,3,4,5]
输出:[[4,5,3],[2],[1]]
解释:
1. 收集叶子节点 [4,5,3],然后删除这些节点
2. 收集叶子节点 [2],然后删除这个节点
3. 收集叶子节点 [1],然后删除这个节点
4. 树为空,结束
示例 2:
输入:[1]
输出:[[1]]
解释:树只有一个节点,直接收集并删除。
提示
- 树中节点数在范围 [1, 100] 内
- -100 <= Node.val <= 100
解题思路
本题可以使用DFS解决:
- 计算每个节点的深度
- 根据深度将节点分组
- 返回分组结果
时间复杂度: O(n),其中n是节点数 空间复杂度: O(h),其中h是树的高度
🎯 算法流程演示

图解思路
节点深度计算
| 节点 | 深度 | 说明 |
|---|---|---|
| 1 | 2 | 根节点 |
| 2 | 1 | 左子节点 |
| 3 | 0 | 右子节点 |
| 4 | 0 | 左叶子节点 |
| 5 | 0 | 右叶子节点 |
分组结果
| 深度 | 节点 | 结果 |
|---|---|---|
| 0 | [4,5,3] | [4,5,3] |
| 1 | [2] | [2] |
| 2 | [1] | [1] |
代码实现
C# 实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
public class Solution {
public IList<IList<int>> FindLeaves(TreeNode root) {
var result = new List<IList<int>>();
GetHeight(root, result);
return result;
}
private int GetHeight(TreeNode node, List<IList<int>> result) {
if (node == null) return -1;
int height = Math.Max(GetHeight(node.left, result), GetHeight(node.right, result)) + 1;
if (height >= result.Count) {
result.Add(new List<int>());
}
result[height].Add(node.val);
return height;
}
}
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 findLeaves(self, root: TreeNode) -> List[List[int]]:
def get_height(node):
if not node:
return -1
height = max(get_height(node.left), get_height(node.right)) + 1
if height >= len(result):
result.append([])
result[height].append(node.val)
return height
result = []
get_height(root)
return result
C++ 实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> findLeaves(TreeNode* root) {
vector<vector<int>> result;
getHeight(root, result);
return result;
}
private:
int getHeight(TreeNode* node, vector<vector<int>>& result) {
if (!node) return -1;
int height = max(getHeight(node->left, result), getHeight(node->right, result)) + 1;
if (height >= result.size()) {
result.push_back({});
}
result[height].push_back(node->val);
return height;
}
};
执行结果
C# 实现
- 执行用时:92 ms
- 内存消耗:24.8 MB
Python 实现
- 执行用时:28 ms
- 内存消耗:14.2 MB
C++ 实现
- 执行用时:4 ms
- 内存消耗:8.4 MB
性能对比
| 语言 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| C++ | 4 ms | 8.4 MB | 执行效率最高,内存占用最小 |
| Python | 28 ms | 14.2 MB | 代码简洁,内存占用适中 |
| C# | 92 ms | 24.8 MB | 类型安全,内存占用较大 |
代码亮点
- 🎯 使用DFS计算节点深度
- 💡 动态扩展结果数组
- 🔍 处理空节点情况
- 🎨 代码结构清晰,易于维护
常见错误分析
- 🚫 未处理空树情况
- 🚫 深度计算错误
- 🚫 数组越界
- 🚫 内存泄漏
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| DFS | O(n) | O(h) | 高效,实现简单 | 需要递归栈空间 |
| BFS | O(n) | O(n) | 直观,易于理解 | 需要额外空间 |
相关题目
- LeetCode 102. 二叉树的层序遍历 - 中等
- LeetCode 107. 二叉树的层序遍历 II - 中等
- LeetCode 199. 二叉树的右视图 - 中等
📖 系列导航
🔥 算法专题合集 - 查看完整合集
📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第366题。
💬 互动交流
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
- 👍 点个赞,让更多人看到这篇文章
- 📁 收藏文章,方便后续查阅复习
- 🔔 关注作者,获取更多高质量算法题解
- 💭 评论区留言,分享你的解题思路或提出疑问
你的支持是我持续分享的动力!
💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!