【LeetCode二叉树#07】左叶子节点之和(基于栈的迭代法前中后序遍历复习)
左叶子节点之和
计算给定二叉树的所有左叶子之和。
示例:

思路
注意审题,这里是要求 左叶子节点 之和
不是二叉树中的左侧节点之和,因此使用层序遍历是不合适的
我们要明确的是,到底什么是左叶子节点
举个例子:

根据上图以及题目给的例子可知,我们无法直接判断当前节点是否为左叶子节点(因为无法将其与左侧节点区分)
所以需要通过当前节点的父节点来判断其左孩子是不是左叶子
即:如果某一节点的左子节点不为空,但该左子节点自身的左右节点为空,则找到一个左叶子节点
处理逻辑:
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】左叶子节点之和(基于栈的迭代法前中后序遍历复习)的更多相关文章
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)
链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...
- Binary Tree Traversal 二叉树的前中后序遍历
[抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...
- C++二叉树前中后序遍历(递归&非递归)统一代码格式
统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...
- Qt实现 动态化遍历二叉树(前中后层次遍历)
binarytree.h 头文件 #ifndef LINKEDBINARYTREE_H #define LINKEDBINARYTREE_H #include<c++/algorithm> ...
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- C语言二叉树的创建、(先中后序)遍历以及存在的问题
#include<stdlib.h> #include<stdio.h> #define True 1 #define False 0 typedef char TElemTy ...
- 飘逸的python - 极简的二叉树前中后序通杀函数
对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...
- Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树
Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树 Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序 ...
- 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历
二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...
随机推荐
- [转帖]python读取配置文件获取所有键值对_python总结——处理配置文件(ConfigParser)
python处理ConfigParser 使用ConfigParser模块读写ini文件 (转载) ConfigParserPython 的ConfigParser Module中定义了3个类对INI ...
- Linux 查询最近占用内存最多的十个进程的方法
ps -eo rss,pid,user,command --sort -rss | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { ...
- vue写组件时的命名规范
1组件命名驼峰 如myBread.vue(组件) 2引入时,接受同样是驼峰 import MyBread from "@/components/cuscom/myBread.vue" ...
- vue报错:'XX' is defined but never used no-unused-vars
参考地址:http://www.gold404.cn/info/87 导致这个报错的原因就是eslint校验, 就是你当初在vue创建脚手架的时候选择了eslint校验: 后面你绝对会碰到这样的报错, ...
- windowsbat命令大全
Bat文件的创建及其命令大全 一.bat文件的创建 新建txt文本文件 向文本文件中输入命令 保存并修改文本文件后缀为.bat 双击保存后的bat文件,运行 二.bat命令大全 echo 和 @ @ ...
- C/C++ 使用CRC检测磁盘文件完整性
当软件被开发出来时,为了增加软件的安全性,防止被破解,通常情况下都会对自身内存或磁盘文件进行完整性检查,以防止解密者修改程序,我们可以将exe与dll文件同时做校验,来达到相互认证的目的,解密者想要破 ...
- 搭建私有仓库Registry(Docker Hub)
搭建私有仓库Registry(Docker Hub) 安装Docker 拉取仓库镜像:# docker pull registry 生成认证certificate mkdir ~/certs open ...
- 一篇带你掌握cmake入门|了解cmake|掌握cmake基本操作
一篇带你掌握cmake入门 内容出处: 作者: 苏丙榅 链接: https://subingwen.cn/cmake/CMake-primer/ 来源: 爱编程的大丙 著作权归作者所有.商业转载请联系 ...
- Java并发(六)----线程start、run、state方法
1.start 与 run 调用 run public static void main(String[] args) { Thread t1 = new Thread("t1&quo ...
- 完蛋,我被offer包围了|秋招自救指南
前言 白泽时隔8年终于记起了b站的密码,这篇文章的视频讲解版已经上传,出镜怪不好意思的,后面写技术文章也会同步用视频的方式讲解,期待您的关注. 公众号:白泽talk,交流群:622383022. 大家 ...