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
相关推荐
超级码力6665 小时前
【Latex文件架构】Latex文件架构模板
算法·数学建模·信息可视化
穿条秋裤到处跑5 小时前
每日一道leetcode(2026.04.29):二维网格图中探测环
算法·leetcode·职场和发展
Merlos_wind5 小时前
HashMap详解
算法·哈希算法·散列表
汉克老师6 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
Yzzz-F8 小时前
Problem - 2205D - Codeforces
算法
智者知已应修善业9 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn9 小时前
Java Set集合相关知识点
java·开发语言·算法
生成论实验室10 小时前
《事件关系阴阳博弈动力学:识势应势之道》第四篇:降U动力学——认知确定度的自驱演化
人工智能·科技·神经网络·算法·架构
AI科技星10 小时前
全域数学·72分册:场计算机卷【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
科研前沿11 小时前
镜像孪生VS视频孪生核心技术产品核心优势
大数据·人工智能·算法·重构·空间计算