
本文转载自微信公众号「代码随想录」,做多左叶之和作者程序员Carl 。题目转载本文请联系代码随想录公众号。做多左叶之和
左叶子之和
题目地址:https://leetcode-cn.com/problems/sum-of-left-leaves/
计算给定二叉树的题目所有左叶子之和。
示例:

思路
首先要注意是做多左叶之和判断左叶子,不是题目二叉树左侧节点,所以不要上来想着层序遍历。做多左叶之和
因为题目中其实没有说清楚左叶子究竟是题目什么节点,那么我来给出左叶子的做多左叶之和明确定义:如果左节点不为空,且左节点没有左右孩子,题目那么这个节点就是做多左叶之和左叶子
大家思考一下如下图中二叉树,左叶子之和究竟是题目多少?

其实是0,因为这棵树根本没有左叶子!
那么判断当前节点是做多左叶之和不是左叶子是无法判断的,必须要通过节点的题目父节点来判断其左孩子是不是左叶子。
如果该节点的做多左叶之和左节点不为空,该节点的左节点的左节点为空,服务器租用该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) { 左叶子节点处理逻辑 } 递归法
递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。。
递归三部曲:
1.确定递归函数的参数和返回值
判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为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<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; } }; 总结
这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。
此时就要通过节点的父节点来判断其左孩子是不是左叶子了。
平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。
希望通过这道题目,可以扩展大家对二叉树的解题思路。
其他语言版本
Java
递归
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 != null && root.left.left == null && root.left.right == null) { // 中 midValue = root.left.val; } int sum = midValue + leftValue + rightValue; return sum; } } 迭代
class Solution { public int sumOfLeftLeaves(TreeNode root) { if (root == null) return 0; Stack<TreeNode> stack = new Stack<> (); stack.add(root); int result = 0; while (!stack.isEmpty()) { TreeNode node = stack.pop(); if (node.left != null && node.left.left == null && node.left.right == null) { result += node.left.val; } if (node.right != null) stack.add(node.right); if (node.left != null) stack.add(node.left); } return result; } } Python
递归
class Solution: def sumOfLeftLeaves(self, root: TreeNode) -> int: if not root: return 0 left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左 right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右 cur_left_leaf_val = 0 if root.left and not root.left.left and not root.left.right: cur_left_leaf_val = root.left.val # 中 return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum 迭代
class Solution: def sumOfLeftLeaves(self, root: TreeNode) -> int: """ Idea: Each time check current nodes left node. If current node dont have one, skip it. """ stack = [] if root: stack.append(root) res = 0 while stack: # 每次都把当前节点的站群服务器左节点加进去. cur_node = stack.pop() if cur_node.left and not cur_node.left.left and not cur_node.left.right: res += cur_node.left.val if cur_node.left: stack.append(cur_node.left) if cur_node.right: stack.append(cur_node.right) return res