题目
给你一棵二叉树的根节点 root
,请你返回 层数最深的叶子节点的和 。原题链接
示例
输入:root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
输出:15
解法一: 层序遍历
考虑到该题涉及树深度,因此直观思路通过层序遍历树结构,取最深层并把节点数累加,即为最终答案。树的层序遍历一般使用队列实现,具体实现逻辑如下:
class Solution {
public int deepestLeavesSum(TreeNode root) {
// 基本信息初始化
if(root == null)return 0;
Queue<TreeNode> queue= new LinkedList<>();
// 根节点提前入队
queue.add(root);
int ans = 0;
// 若队列中还有数据,则树结构尚未遍历完,继续遍历
while(!queue.isEmpty()){
// 循环取每层数据,并计算每层节点的数据和
ans = 0;
int size = queue.size();
// 通过size控制把树结构中同层数据输出,计算每层结果
for(int i = 0; i < size; ++i){
TreeNode temp = queue.poll();
ans += temp.val;
// 左右子树非空,则入队
if(temp.left != null){
queue.add(temp.left);
}
if(temp.right != null){
queue.add(temp.right);
}
}
}
return ans;
}
}
其执行效果如下:
执行用时:6 ms, 在所有 Java 提交中击败了53.91%的用户
内存消耗:43.7 MB, 在所有 Java 提交中击败了67.43%的用户
解法二: DFS
一般来说,树,图的相关操作除了BFS(广度优先外),还能考虑从DFS(深度优先角度做)。
分析后把问题的主要任务拆解为两部分:
- 确定最深层;
- 计算最深层叶子节点和;
在该题,只需解决以上两个问题。因此简单实现可以通过一遍遍历确认最大深度,再一次遍历统计叶子节点和,完成该题。考虑是否能把两个任务用一次遍历实现,可以发现:
- 当节点是叶子节点时,判断其深度与当前最大深度的大小:
- 若深度小于当前最大深度,该节点不符合条件,跳过;
- 若深度等于当前最大深度,该节点可能为最大层节点(当前最大深度不一定为实际树的最大深度),计算当前该层和;
- 若深度大于当前最大深度,更新最大深度,把当前计算和重置为当前叶子节点的值;
- 当前节点不是叶子节点,继续DFS遍历;
可以做到用一次遍历完成任务。具体实现逻辑如下:
class Solution {
// 初始化和ans为0,最大深度为-1;
int ans = 0;
int maxDepth = -1;
public int deepestLeavesSum(TreeNode root) {
if(root == null)return 0;
// 开始深度遍历
dfs(root, 0);
return ans;
}
public void dfs(TreeNode root ,int depth){
// 处理空树
if(root == null){
return;
}
// 若为叶子结点
if(root.left == null && root.right == null){
// 大于最大深度,重置数据
if(maxDepth < depth){
maxDepth = depth;
ans = root.val;
return;
}else if(maxDepth == depth){
// 等于最大深度,求和
ans += root.val;
return;
}
// 小于最大深度,跳过
return;
}
// 不是叶子节点,深度搜索左右子树
dfs(root.left, depth + 1);
dfs(root.right, depth + 1);
}
}
其执行效果如下:
执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:44.2 MB, 在所有 Java 提交中击败了23.29%的用户