其实对于叶子节点的处理,依旧是通过遍历进行处理,往往使用先序遍历并稍加改动即可,在进行先序遍历时,首先处理中间节点,但进行判断,若是叶子节点,则进行符合题目要求逻辑的处理,若不是叶子节点则不处理;然后递归调用处理其左右子树。
对于递归遍历方法,要多多品味,比较有意思,什么时候停止,每一次进行了什么处理并会产生什么影响,这些是递归中需要思考的。
1、leetcode872题
题目描述:
请考虑一颗二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。
举个例子,如上图所示,给定一颗叶值序列为 (6, 7, 4, 9, 8)
的树。
如果有两颗二叉树的叶值序列是相同,那么我们就认为它们是 叶相似 的。
如果给定的两个头结点分别为 root1
和 root2
的树是叶相似的,则返回 true
;否则返回 false
。
提示:
- 给定的两颗树可能会有
1
到100
个结点。
解决思路及代码:
class Solution {
//通过先序遍历处理所有的节点,判断当前节点是否为叶子节点,并将叶子节点加入存储值的字符串中
//先序遍历,先处理中间节点,后处理左右子树
//处理中间节点时并非将所有的中间节点进行处理,此处需要对先序遍历稍加改动,只处理叶子节点
public boolean leafSimilar(TreeNode root1, TreeNode root2) {
String sr1 = leaf(root1);
String sr2 = leaf(root2);
return sr1.equals(sr2);
}
//该方法得到一颗树的叶值序列
private String leaf(TreeNode root){
//递归深层处结束退出
if(root == null){
return null;
}
//先序遍历处理当前节点
String result = "";
if(root.left == null && root.right == null){
result += root.val;
}
//先序遍历处理左右子树
if(root.left != null){
result += leaf(root.left);
}
if(root.right != null){
result += leaf(root.right);
}
return result;
}
}
2.leetcode404题
题目描述:
计算给定二叉树的所有左叶子之和。
示例:
3 / \ 9 20 / \ 15 7 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
解决思路及代码:
class Solution {
//如何判断一个节点是左叶子节点呢
//首先想到如果直接看一个节点,由于树的向下可查,向上不可查的特性,是没有办法直接判断出一个节点是左叶子节点的
//仔细想一下,如果看该节点的父节点就可以判断该节点是否为左叶子节点了
//因此判断一个节点时,应从其父节点入手
//每次处理的当前节点,判断其左子节点是否为叶子节点,即可实现寻找左子节点
public int sumOfLeftLeaves(TreeNode root) {
int sum = 0;
if(root != null){
//root的左子节点不为空
if(root.left != null){
//root的左子节点为叶子节点
if(root.left.left == null && root.left.right == null){
sum += root.left.val;
}
//root的左子节点非叶子节点,递归处理root的左子节点
sum += sumOfLeftLeaves(root.left);
}
//root的右子节点不为空
if(root.right != null){
//递归处理root的右子节点
sum += sumOfLeftLeaves(root.right);
}
}
return sum;
}
}