LeetCode-1302 层数最深叶子节点的和

题目描述

给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和

示例 1:

1
2
输入:root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
输出:15

示例 2:

1
2
输入:root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
输出:19

提示:

  • 树中节点数目在范围 $[1, 10 ^ 4]$ 之间。
  • $1 \leq Node.val \leq 100$

深度优先搜索 DFS - $O(N)$

DFS

只需要遍历一遍树,找到所有叶子节点,此时判断:

  • 当前叶子节点深度 小于 当前最深深度,则跳过
  • 当前叶子节点深度 等于 当前最深深度,则 最深深度节点权值和加上当前节点权值
  • 当前叶子节点深度 大于 当前最深深度,则 更新最深深度,以及更新最深深度节点权值和为当前节点的权值

由于 非叶子节点深度一定低于叶子节点,因此对于所有节点都可以进行上述判断,代码可以写的更短一些

题目中第一个实例的更新过程如下图所示

  • 当前节点深度 小于 当前最深深度。
    • 如图中的 d: 2 < 3 表示当前节点深度为 d = 2,枚举当前节点之前最深深度为 3
    • 那么 d: 2 < 3 跳过
  • 当前节点深度 等于 当前最深深度。
    • 如图中的 d: 0 = 0 表示当前节点深度为 d = 0,枚举当前节点之前最深深度为 0
    • 两者相等:因此要将当前节点权值 加入 最大深度节点权值和中
  • 当前节点深度 大于 当前最深深度。如图中
    • 如图中的 d: 1 > 0 表示当前节点深度为 d = 1,枚举当前节点之前最深深度为 0
    • 由于大于最深深度,因此要更新最深深度,以及 重新计算权值和(初始化为当前节点的权值)
  • 按照前序遍历枚举树中的每个节点

时间复杂度 - $O(N)$

  • 枚举一遍树中的所有节点,树节点数量为 $N$,因此复杂度为 $O(N)$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func deepestLeavesSum(root *TreeNode) int {
// LeetCode 多组用例测试,全局变量修改会影响后面测试用例
// 因此要初始化为 0
sum, depth = 0, 0
// 从根节点开始进行 DFS,根节点深度记为 0
dfs(root, 0)
// 返回答案:最大深度节点权值和
return sum
}

// sum: 最大深度节点权值和
// depth:最大深度
var sum, depth int

// u: 当前前序遍历枚举到的节点
// d: 当前节点的深度
func dfs(u *TreeNode, d int) {
// 如果搜索到空节点,则返回
if u == nil { return }
// 如果当前深度 d > depth 也就是大于最大深度,则重新计算权值和
// depth 更新为当前深度,sum 更新为当前节点权值
if d > depth {
depth = d
sum = u.Val
} else if d == depth {
// 如果当前深度 d = detph,那么将当前节点权值加入到最大深度节点权值和中
sum += u.Val
}
// 前序遍历,枚举树
dfs(u.Left, d + 1); dfs(u.Right, d + 1)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 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:
int sum = 0, depth = 0;

void dfs(TreeNode* u, int d) {
if (!u) return ;
if (d > depth) depth = d, sum = u->val;
else if (d == depth) sum += u->val;
dfs(u->left, d + 1), dfs(u->right, d + 1);
}

int deepestLeavesSum(TreeNode* root) {
dfs(root, 0);
return sum;
}
};