力扣 404 左叶子之和【递归三步法】【寻找叶节点】

力扣 404 左叶子之和【递归三步法】

全部刷题与学习记录

【C++刷题学习笔记目录】

【C++百万并发网络通信-笔记目录】

原题目

题目地址:404. 左叶子之和

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

示例:

    3
   / \
  9  20
    /  \
   15   7

在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

考查知识点

递归三步法、叶节点的特殊性

自己的第一遍解法

一上来就没理解题意,题目要求的是左叶子,并不是左子节点。如果是求左子节点之和,就直接遍历所有的节点,将不为空的左子节点值累计起来就行,没有看清题意的我是这样做的。

好的解法

【代码随想录】中指出了这种理解上的误区,那么左子节点左叶子究竟有什么不一样呢?

**如果一个节点没有leftright子节点,说明该节点是一个叶节点!**怎么区分叶节点是左右?这是针对叶节点的父节点来说的,因为只有从叶节点的父节点角度出发,才能知晓它的子节点方向性(左/右)。

左叶子的判断条件为:当前节点的左子节点非空,且左子节点没有子节点

我们使用递归三步法:

  • 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带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。

参考:

C++的STL中accumulate的用法

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

猜你喜欢

转载自blog.csdn.net/weixin_44484715/article/details/115334003