二叉树:做了这么多题目了,我的左叶子之和是多少?
Posted 代码随想录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树:做了这么多题目了,我的左叶子之和是多少?相关的知识,希望对你有一定的参考价值。
❝概念必须弄清楚,什么是左叶子
❞
404.左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
思路
「首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。」
其实题目说的也很清晰了,左和叶子我们都知道表示什么,那么左叶子也应该知道了,但为了大家不会疑惑,我还是来给出左叶子的明确定义:「如果左节点不为空,且左节点没有左右孩子,那么这个节点就是左叶子」
大家思考一下如下图中二叉树,左叶子之和究竟是多少?
「其实是0,因为这棵树根本没有左叶子!」
那么「判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。」
如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
左叶子节点处理逻辑
}
递归法
递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。。
递归三部曲:
-
确定递归函数的参数和返回值
判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int
使用题目中给出的函数就可以了。
-
确定终止条件
依然是
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 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<TreeNode*> 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-------
我将算法学习相关的资料已经整理到了Github :https://github.com/youngyangyang04/leetcode-master,里面还有leetcode刷题攻略、各个类型经典题目刷题顺序、思维导图看一看一定会有所收获,如果给你有帮助给一个star支持一下吧!
每天8:35准时推送一道经典算法题目,推送的每道题目都不是孤立的,而是由浅入深,环环相扣,帮你梳理算法知识脉络,轻松学算法!
以上是关于二叉树:做了这么多题目了,我的左叶子之和是多少?的主要内容,如果未能解决你的问题,请参考以下文章
LeetCodeSum of Left Leaves 左叶子之和