【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): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...
随机推荐
- [转帖]关于linux:NUMA架构下的内存延迟区别测试
https://lequ7.com/guan-yu-linuxnuma-jia-gou-xia-de-nei-cun-yan-chi-qu-bie-ce-shi.html 当初的服务器物理机CPU个别 ...
- mysql系列14---mysql数据库还原与备份
一.Liunx服务器下数据库定时备份 1.编写mysql在docker容器中备份的shell脚本: #!/bin/bash# 2020-11-15#docker启动的mysql备份mysql_use ...
- Fabric区块链浏览器(1)
本文是区块链浏览器系列的第三篇,本文介绍区块链浏览器的主体部分,即区块数据的解析. 这一版本的区块链浏览器是基于gin实现的,只提供三种接口: /block/upload:POST,上传Protobu ...
- 在K8S中,静态、动态、自主式Pod有何区别?
在Kubernetes(简称K8s)中,静态Pod.自主式Pod和动态Pod是不同管理方式下的Pod类型,它们的区别主要体现在创建和管理方式上: 静态Pod: 静态Pod是由kubelet直接管理的, ...
- C# 使用字典将枚举转换为String
枚举 public enum ColorType { Red = 10, Blue = 20, Green = 30, Yellow = 40, } String var A1 = "AAA ...
- git checkout switch restore
前言 在 Git 术语中,"checkout"是在目标实体的不同版本之间切换的行为.该命令对三个不同的实体进行操作:文件.提交和分支.除了"checkout"的 ...
- C/C++ 动态解密释放ShellCode
今天在复习<加密与解密>时,在软件保护这一章中有一个代码与数据结合的案例,其原理是将代码段中的代码进行xor异或加密处理以后回写到原始位置,当程序运行后将此处的内容动态的进行解密,解密后回 ...
- 移动端跨平台动效工具Lottie, PAG的使用
动效工具Lottie Lottie 是 Airbnb 开源的一套跨平台的完整的动画效果解决方案,设计师可以使用 Adobe After Effects 设计出漂亮的动画之后,使用 Lottic 提 ...
- 苹果打破12年惯例:iPad一整年未更新
1月2日消息,据媒体报道,自2010年首次亮相以来,苹果一直保持着每年至少发布一款新型号的传统. 但是在过去的2023年,苹果没有发布iPad,2023年苹果发布的唯一与iPad相关的产品是USB-C ...
- 基于Wireshark的ARP协议分析和IP报文、ICMP报文的分析|网络数据抓包|课程设计|traceroute|ping|
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...