左叶子节点之和

力扣题目链接(opens new window)

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

示例:

思路

注意审题,这里是要求 左叶子节点 之和

不是二叉树中的左侧节点之和,因此使用层序遍历是不合适的

我们要明确的是,到底什么是左叶子节点

举个例子:

根据上图以及题目给的例子可知,我们无法直接判断当前节点是否为左叶子节点(因为无法将其与左侧节点区分)

所以需要通过当前节点的父节点来判断其左孩子是不是左叶子

即:如果某一节点的左子节点不为空,但该左子节点自身的左右节点为空,则找到一个左叶子节点

处理逻辑:

if(node->left != NULL  && node->left->left == NULL && node->right->right == NULL){
//左叶子节点处理逻辑
}

本题仍然有递归和迭代两种解法

递归法

分析

三部曲

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

输入是根节点(每次的输入节点即为本次递归的根节点),返回值是左叶子节点之和,即int

2、确定终止条件

终止条件有两个,因为这里输入递归函数的“根节点”其实就是当前节点

如果当前节点为空,那么终止

如果当前节点以及是做叶子节点,那么也应该终止

if(root == NULL) return 0;
if(root->left == NULL &&root->right == NULL) return 0;

3、确定单层处理逻辑(即当前递归层的处理逻辑)

使用后序遍历的方式通过递归不断遍历左右子节点,并寻找左右子节点下的左叶子节点

如果遇到的话,就获取该节点的val,然后在每层递归返回值的时候累加左右子节点下的左叶子节点的值之和

//定义变量,存放左子节点的左叶子节点的值之和
int leftSum = sumOfLeftLeaves(root->left);//左
//找到左叶子节点
if(root->left != NULL && root->left->left == NULL && root->left->right == NULL){
leftSum = root->left->val;
}
//以上两行代码对应过程是”使用父节点来判断其左孩子是不是左叶子节点“ int rightSum = sumOfLeftLeaves(root->right);//右 int sum = leftSum + rightSum;//中
return sum;

一定要明确左叶子节点的概念

虽然我们也遍历右节点,但是是为了寻找右节点下是否有左子节点,该子节点下又是否进一步存在左叶子节点

所以当遍历到某个右节点,那之后的递归操作一定会持续到触发leftSum为止(即在该右节点的子节点中找到叶子节点)

代码
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
//确定终止条件
if(root == NULL) return 0;
if(root->left == NULL && root->right == NULL) return 0; //确定单层处理逻辑
//后序遍历
//定义变量,存放左子节点的左叶子节点的值之和
int leftSum = sumOfLeftLeaves(root->left);//左
//找到左叶子节点
if(root->left != NULL && root->left->left == NULL && root->left->right == NULL){
leftSum = root->left->val;
}
//以上两行代码对应过程是”使用父节点来判断其左孩子是不是左叶子节点“
int rightSum = sumOfLeftLeaves(root->right);//右 int sum = leftSum + rightSum;//中
return sum; }
};
注意

TBD

迭代法

分析

使用前中后序遍历都可以,具体操作和使用栈进行迭代法遍历一致

代码
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
//创建一个栈
stack<TreeNode*> st;
//判断根节点
if (root != NULL) st.push(root);
//定义结果变量
int res = 0;
while(!st.empty()){
//取出栈顶节点
TreeNode* node = st.top();
//弹出
st.pop();
//判断左叶子节点
if(node->left != NULL && node->left->left == NULL && node->left->right == NULL){
res += node->left->val;
}
//遍历左右子节点,压栈
if (node->left) st.push(node->left);
if (node->right) st.push(node->right);
}
return res;
}
};
注意

使用栈进行迭代法的前后序遍历时,要与层序遍历区分清楚

在while中,迭代法前后序遍历不需要记录当前栈的长度

【LeetCode二叉树#07】左叶子节点之和(基于栈的迭代法前中后序遍历复习)的更多相关文章

  1. [C++] 非递归实现前中后序遍历二叉树

    目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...

  2. POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)

    链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...

  3. Binary Tree Traversal 二叉树的前中后序遍历

    [抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...

  4. C++二叉树前中后序遍历(递归&非递归)统一代码格式

    统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...

  5. Qt实现 动态化遍历二叉树(前中后层次遍历)

    binarytree.h 头文件 #ifndef LINKEDBINARYTREE_H #define LINKEDBINARYTREE_H #include<c++/algorithm> ...

  6. 二叉树前中后/层次遍历的递归与非递归形式(c++)

    /* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...

  7. C语言二叉树的创建、(先中后序)遍历以及存在的问题

    #include<stdlib.h> #include<stdio.h> #define True 1 #define False 0 typedef char TElemTy ...

  8. 飘逸的python - 极简的二叉树前中后序通杀函数

    对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...

  9. Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树

    Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树 Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序 ...

  10. 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历

    二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...

随机推荐

  1. [转帖]Linux命令拾遗-硬件资源观测

    https://www.cnblogs.com/codelogs/p/16060455.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 这是Linux ...

  2. [转帖]SystemStap、BCC、bpftrace

    https://plantegg.github.io/2019/09/16/SystemStap/ Linux 4.4+ 支持 eBPF.基于 eBPF 可以将任何内核函数调用转换成可带任何 数据的用 ...

  3. redis 6源码解析之 dict

    edis源码的dict.c主要实现了基于hash表的操作,如增删改查,对哈希表大小的扩容和缩容,以及对哈希表的rehash和增量rehash等.在源码的dictScan函数中,非常巧妙精美地实现了对哈 ...

  4. fiddler如何抓取https请求

    pc端browse 1.打开下载好的fiddler,点击tools选择options后进入https tab下,勾选Decrypt  HTTPS CONNECTS 和Ignore server cer ...

  5. Ant Design Vue分页Pagination

    <template> <div> <a-pagination show-quick-jumper v-model:current="current1" ...

  6. 纯c#运行开源本地大模型Mixtral-8x7B

    先看效果图,这是一个比较典型的逻辑推理问题,以下是本地运行的模型和openai gpt3.5的推理对比 本地运行Mixtral-8x7B大模型: chatgpt3.5的回答: 关于Mixtral 8x ...

  7. windowsbat删除命令

    widnwosbat命令 DEL /F /A /Q \?%1 用于删除指定路径下的文件,参数含义如下: /F: Force delete,即强制删除: /A: 用于指定文件属性,A代表存档,D代表目录 ...

  8. 8.2 Windows驱动开发:内核解锁与强删文件

    在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用ObSet ...

  9. Python 检测PE所启用保护方式

    Python 通过pywin32模块调用WindowsAPI接口,实现对特定进程加载模块的枚举输出并检测该PE程序模块所启用的保护方式,此处枚举输出的是当前正在运行进程所加载模块的DLL模块信息,需要 ...

  10. Pdfium.Net.Free 一个免费的Pdfium的 .net包装器--打开大文件处理

    项目地址: Pdfium.Net:https://github.com/1000374/Pdfium.Net PdfiumViewer:https://github.com/1000374/Pdfiu ...