目录
一、力扣110.平衡二叉树
1.1 题目
1.2 思路
递归:采用后序遍历的方式,获取到左右两个孩子的高度,然后判断相减的绝对值是否不超过1;
关键点:当某个节点已经不满足平衡二叉树的条件时,就没必要向上层父节点返回他的高度了,因为整个二叉树已经不是平衡二叉树了,我们规定向上返回-1,上层节点判断如果左右子树有返回-1的那么就直接向上返回-1.
1.3 代码
class Solution {
public boolean isBalanced(TreeNode root) {
int result = getHeight(root);
if(result == -1){
return false;
}
return true;
}
//递归函数
public int getHeight(TreeNode node){
if(node == null){
return 0;
}
int leftHeight = getHeight(node.left);
if(leftHeight == -1){
return -1;
}
int rightHeight = getHeight(node.right);
if(rightHeight == -1){
return -1;
}
if(Math.abs(leftHeight-rightHeight) > 1){
return -1;
}else{
return Math.max(leftHeight,rightHeight)+1;
}
}
}
1.4 总结
平衡二叉树的概念:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1.
二、力扣257.二叉树的所有路径
2.1 题目
2.2 思路
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
2.3 代码
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
if(root == null){
return res;
}
traversal(root,path,res);
return res;
}
//递归函数
public void traversal(TreeNode node,List<Integer> path,List<String> res){
//前序遍历:中左右
path.add(node.val);
if(node.left == null && node.right ==null){
//找到了叶子结点,将当前路径加入res结果集
StringBuilder sb = new StringBuilder();
for(int i =0;i<path.size()-1;i++){
sb.append(path.get(i)+"->");
}
sb.append(path.get(path.size()-1));
res.add(sb.toString());
return;
}
//如果还没有到叶子节点,继续向下递归
if(node.left != null){
traversal(node.left,path,res);
path.remove(path.size()-1);
}
if(node.right != null){
traversal(node.right,path,res);
path.remove(path.size()-1);
}
}
}
2.4 总结
回溯还是理解的不太深刻,后续还需要熟悉。
三、力扣404.左叶子之和
3.1 题目
给定二叉树的根节点root,返回所有的左叶子之和。
左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点
3.2 思路
递归函数返回的是本节点的左子树左叶子节点和右子树左叶子节点之和。
递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。
判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int
使用题目中给出的函数就可以了。
如果遍历到空节点,那么左叶子值一定是0。
注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。 所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,那么终止条件为:
当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。
3.3 代码
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
return traversal(root);
}
//递归函数:后续遍历,收集左子树和右子树的左叶子节点之和
public int traversal(TreeNode node){
if(node == null){
return 0;
}
int leftNum = traversal(node.left);
if(node.left != null && node.left.left ==null && node.left.right == null){
leftNum = node.left.val;
}
int rightNum = traversal(node.right);
return leftNum+rightNum;
}
}
3.4 总结
解题关键:判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。