leetcode算法(404.左叶子之和)

层序遍历

cpp 复制代码
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        // 创建一个队列用于BFS(广度优先搜索)
        queue<TreeNode*> que;
        
        // 如果根节点为空,直接返回0
        if(root == NULL) return 0;
        
        // 将根节点加入队列
        que.push(root);
        
        // 用于累加左叶子节点的和
        int sum = 0;
        
        // BFS主循环:当队列不为空时继续处理
        while(!que.empty()){
            // 获取当前层的节点数量
            int size = que.size();
            
            // 遍历当前层的所有节点
            for(int i = 0; i < size; i++){
                // 取出队列前面的节点
                TreeNode *node = que.front();
                que.pop();
                
                // 如果当前节点有左子节点
                if(node->left){
                    // 将左子节点加入队列(用于后续遍历)
                    que.push(node->left);
                    
                    // 检查左子节点是否是叶子节点
                    // 叶子节点:既没有左子节点也没有右子节点
                    if(node->left->left == NULL && node->left->right == NULL){
                        // 如果是左叶子节点,累加其值到sum
                        sum += node->left->val;
                    }
                } 
                
                // 如果当前节点有右子节点,将其加入队列
                if(node->right)  que.push(node->right);
            }
        }
        
        // 返回所有左叶子节点的和
        return sum;
    }
};

代码逻辑说明

  1. 使用队列进行层序遍历(BFS)

  2. 对每个节点检查其左子节点是否存在

  3. 如果存在左子节点,先将其加入队列(无论它是不是叶子节点)

  4. 然后判断这个左子节点是否是叶子节点(没有左右子节点)

  5. 如果是叶子节点,累加它的值

  6. 继续处理右子节点(将其加入队列)

二叉树递归法

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

递归三部曲:

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

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

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

2.确定终止条件

如果遍历到空节点,那么左叶子值一定是0

cpp 复制代码
if (root == NULL) return 0;

注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。

所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,那么终止条件为:

cpp 复制代码
if (root->left == NULL && root->right== NULL)  return 0;
//其实这个也可以不写,如果不写不影响结果,但就会让递归多进行了一层。

3.确定单层递归的逻辑

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

cpp 复制代码
int leftValue = sumOfLeftLeaves(root->left);    // 左
if (root->left && !root->left->left && !root->left->right) {
    leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right);  // 右

int sum = leftValue + rightValue;               // 中
return sum;

整体递归代码如下:

cpp 复制代码
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        // 1. 基本情况1: 如果当前节点为空,返回0
        if (root == NULL) return 0;
        
        // 2. 基本情况2: 如果当前节点是叶子节点(没有左右子节点)
        //    注意:这里叶子节点返回0,因为叶子节点本身不是左叶子
        //    只有作为左子节点的叶子才需要计算
        if (root->left == NULL && root->right == NULL) return 0;

        // 3. 递归计算左子树中的所有左叶子节点之和
        //    注意:这个递归调用可能会返回0,即使左子节点是叶子节点
        //    因为上面的基本情况2会让叶子节点返回0
        int leftValue = sumOfLeftLeaves(root->left);    // 左

        // 4. 关键判断:如果当前节点的左子节点存在,并且是叶子节点
        //    !root->left->left:左子节点没有左子节点
        //    !root->left->right:左子节点没有右子节点
        //    满足这两个条件说明左子节点是叶子节点
        if (root->left && !root->left->left && !root->left->right) {
            // 5. 覆盖之前递归计算的结果
            //    因为递归调用sumOfLeftLeaves(root->left)会返回0
            //    (左叶子节点本身会返回0,根据基本情况2)
            //    但实际上我们需要计算这个左叶子节点的值
            leftValue = root->left->val;
        }
        
        // 6. 递归计算右子树中的所有左叶子节点之和
        int rightValue = sumOfLeftLeaves(root->right);  // 右

        // 7. 将左右子树的结果相加,得到当前子树的总和
        int sum = leftValue + rightValue;               // 中
        
        // 8. 返回当前子树的所有左叶子节点值之和
        return sum;
    }
};

举例:

复制代码
       3
      / \
     9  20
        / \
       15  7

步骤1:节点3开始执行

复制代码
sumOfLeftLeaves(3):
  root=3
  1. if(root==NULL)不符合
  2. if(3.left==NULL && 3.right==NULL) 不符合 (9和20都不为空)
  3. leftValue = sumOfLeftLeaves(9)  // 入栈

步骤2:节点9开始执行

复制代码
sumOfLeftLeaves(9):
  root=9
  1. if(root==NULL) → 不符合
  2. if(9.left==NULL && 9.right==NULL) → 符合 ,所以return 0 
  执行: return 0  // 出栈
然后节点9返回0,回到节点3

步骤3:节点3继续执行(左子树返回后)

复制代码
sumOfLeftLeaves(3)继续:
  leftValue = 0  // 从sumOfLeftLeaves(9)得到
  
  // 关键判断
  if(3.left && !3.left->left && !3.left->right):
      3.left=9, 9.left=NULL, 9.right=NULL → 条件成立
      leftValue = 9  // 所以leftValue覆盖为9.val,现在leftValue为9
  
  rightValue = sumOfLeftLeaves(20)  // 入栈

......

......

......

复制代码
sumOfLeftLeaves(3)
├── leftValue = sumOfLeftLeaves(9) → 0 → 修正为9
└── rightValue = sumOfLeftLeaves(20)
    ├── leftValue = sumOfLeftLeaves(15) → 0 → 修正为15
    └── rightValue = sumOfLeftLeaves(7) → 0
    └── sum = 15 + 0 = 15
└── sum = 9 + 15 = 24
相关推荐
你撅嘴真丑4 小时前
第九章-数字三角形
算法
uesowys5 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
ValhallaCoder5 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮5 小时前
AI 视觉连载1:像素
算法
智驱力人工智能5 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥6 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风6 小时前
代码随想录第十五天
数据结构·算法·leetcode
XX風6 小时前
8.1 PFH&&FPFH
图像处理·算法
NEXT067 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
代码游侠7 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法