Java二叉树左叶子节点的和_二叉树:做了这么多题目了,我的左叶子之和是多少?...

概念必须弄清楚,什么是左叶子

404.左叶子之和

计算给定二叉树的所有左叶子之和。

示例:

a3fa68ef704a8c114e481098eb844117.png

思路

「首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。」

其实题目说的也很清晰了,左和叶子我们都知道表示什么,那么左叶子也应该知道了,但为了大家不会疑惑,我还是来给出左叶子的明确定义:「如果左节点不为空,且左节点没有左右孩子,那么这个节点就是左叶子」

大家思考一下如下图中二叉树,左叶子之和究竟是多少?

8c784f1b55264aeee19f34cee3b6754b.png

「其实是0,因为这棵树根本没有左叶子!」

那么「判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。」

如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {

左叶子节点处理逻辑

}

递归法

递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。。

递归三部曲:

确定递归函数的参数和返回值

判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int

使用题目中给出的函数就可以了。

2.确定终止条件

依然是

if (root == NULL) return 0;

3.确定单层递归的逻辑

当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。

代码如下:

int leftValue = sumOfLeftLeaves(root->left); // 左

int rightValue = sumOfLeftLeaves(root->right); // 右

// 中

int midValue = 0;

if (root->left && !root->left->left && !root->left->right) {

midValue = root->left->val;

}

int sum = midValue + leftValue + rightValue;

return sum;

整体递归代码如下:

class Solution {

public:

int sumOfLeftLeaves(TreeNode* root) {

if (root == NULL) return 0;

int leftValue = sumOfLeftLeaves(root->left); // 左

int rightValue = sumOfLeftLeaves(root->right); // 右

// 中

int midValue = 0;

if (root->left && !root->left->left && !root->left->right) { // 中

midValue = root->left->val;

}

int sum = midValue + leftValue + rightValue;

return sum;

}

};

以上代码精简之后如下:

class Solution {

public:

int sumOfLeftLeaves(TreeNode* root) {

if (root == NULL) return 0;

int midValue = 0;

if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {

midValue = root->left->val;

}

return midValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);

}

};

迭代法

本题使用了后序遍历啊,那么参考文章 二叉树:听说递归能做的,栈也能做!和二叉树:前中后序迭代方式的写法就不能统一一下么?中的写法,同样可以写出一个后序遍历的迭代法。

判断条件都是一样的,代码如下:

class Solution {

public:

int sumOfLeftLeaves(TreeNode* root) {

stack st;

if (root == NULL) return 0;

st.push(root);

int result = 0;

while (!st.empty()) {

TreeNode* node = st.top();

st.pop();

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {

result += node->left->val;

}

if (node->right) st.push(node->right);

if (node->left) st.push(node->left);

}

return result;

}

};

总结

这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。

此时就要通过节点的父节点来判断其左孩子是不是左叶子了。

「平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。」

希望通过这道题目,可以扩展大家对二叉树的解题思路。

在留言区留下你的思路吧!

-------end-------

另外因为公众号改版,时间线被打乱,一些精彩文章大家可能错过了。如果感觉这里的文章对你有帮助,赶紧给「代码随想录」加一个星标吧,方便第一时间阅读文章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值