当前位置:首页 > IT科技

做了这么多题目了,会求左叶子之和么?

本文转载自微信公众号「代码随想录」,做多左叶之和作者程序员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 

分享到:

滇ICP备2023006006号-16