力扣 404 左叶子之和【递归三步法】
全部刷题与学习记录
原题目
题目地址:404. 左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
3
/ \
9 20
/ \
15 7
在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
考查知识点
递归三步法、叶节点的特殊性
自己的第一遍解法
一上来就没理解题意,题目要求的是左叶子
,并不是左子节点。如果是求左子节点之和,就直接遍历所有的节点,将不为空的左子节点值累计起来就行,没有看清题意的我是这样做的。
好的解法
【代码随想录】中指出了这种理解上的误区,那么左子节点
与左叶子
究竟有什么不一样呢?
**如果一个节点没有left
和right
子节点,说明该节点是一个叶节点!**怎么区分叶节点是左右?这是针对叶节点的父节点来说的,因为只有从叶节点的父节点角度出发,才能知晓它的子节点方向性(左/右)。
左叶子的判断条件为:当前节点的左子节点非空,且左子节点没有子节点
我们使用递归三步法:
-
1、确定递归函数参数及返回值:
使用外部数组
leftValArr
记录所有左叶子的数值,最后统计leftValArr
的数值总和,因此递归函数traverse()
不需要明确的返回值,设为void;因为要不断向下遍历二叉树,所以需要传入当前节点cur
-
2、递归退出条件:
退出条件:
if (cur== nullptr) return;
-
3、单层递归逻辑
向
leftValArr
数组中添加符合条件的左叶子的值后,接着向下递归遍历左右子节点
全部代码如下:
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 {
private:
vector<int> leftValArr;
void traverse(TreeNode* cur) {
if (cur == nullptr) return;
if (cur->left != nullptr && cur->left->left == nullptr && cur->left->right == nullptr)
leftValArr.push_back(cur->left->val);
traverse(cur->left);
traverse(cur->right);
}
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == nullptr) return 0;
traverse(root);
int sumCount = accumulate(leftValArr.begin(), leftValArr.end(), 0);
return sumCount;
}
};
这里介绍一个求和函数accumulate()
,位于numeric
头文件中,
accumulate
带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
参考: