判断平衡二叉树,即判断中间节点的左子树和右子树的高度之差不大于1.使用后序遍历,将左右子树的高度收集起来,相减进行判断。ps:二叉树的深度和高度,从上往下挖是深度,从下往上长是高度,一颗二叉树的最大高度和最大深度在数值上是相同的。
终止条件:节点为null,返回高度0
单层处理逻辑:收集左子树的高度,收集右子树的高度,处理中间节点:判断左子树和右子树的高度差是否大于1。
class Solution {
public boolean isBalanced(TreeNode root) {
int result=getheight(root);
if(result==-1){
return false;
}else{
return true;
}
}
public int getheight(TreeNode node){
if(node==null){
return 0; //返回高度为0
}
int result=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){
result=-1;
}else{
result=1+Math.max(leftheight,rightheight);
}
return result;
}
}
这题没有想出如何使用层序遍历来进行解决。暂时使用递归方法,这里求所有路径就需要求完左子树的所有路径后,保留中间节点继续遍历右子树的所有路径。使用一个path数组来记录路径上的所有节点的数值,当遍历完一条路径之后,将路径保存在结果集中。然后使用回溯,弹出path中的节点,这里递归返回一次就弹出一次,递归和回溯同时进行。最后返回到有右孩子的中间节点处向右孩子方向遍历。
终止条件是遍历到了叶子节点,节点的左孩子和右孩子均为null。
单层的处理逻辑为遍历左子树方向,遍历完左子树中的路径后进行回溯,继续向右子树方向遍历,遍历完右子树中的路径后进行回溯。最后返回结果集。处理中间节点在终止条件之前,因为遍历到叶子节点时,需要将路径添加进结果集中进行返回,如果将中间节点处理放在终止条件之后,将会遗漏最后的叶子节点。
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<Integer> path=new ArrayList<>();
List<String> res=new ArrayList<>();
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){
StringBuilder sb=new StringBuilder();
for(int i=0;i<path.size()-1;i++){//最后一个节点后没有->符号
sb.append(path.get(i)).append("->");
}
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);
}
}
}
使用后序遍历,将中间节点的左子树中的左叶子之和和右子树中的左叶子之和收集起来进行相加返回。
终止条件:遍历到叶子节点,返回0,因为左叶子为0;
单层处理逻辑:遍历左子树,当遇到叶子节点之后会返回到中间节点,此时通过中间节点(父节点)判断该叶子节点是否为左叶子节点,若是左叶子节点,收集其值。接着遍历右子树,右子树不需要再进行判断,因为右子树会进入到上面的逻辑中。中间节点处理:将左子树中的左叶子之和和右子树中的左叶子之和进行相加再返回。
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
return traversal(root);
}
public int traversal(TreeNode node){
if(node==null){
return 0;
}
if(node.left==null&&node.right==null){
return 0;
}
int leftsum=traversal(node.left);
if(node.left!=null&&node.left.left==null&&node.left.right==null){//返回到左叶子
leftsum=node.left.val; //节点的父节点处理
}
int rightsum=traversal(node.right);
int sum=leftsum+rightsum;
return sum;
}
}
层序遍历法
在层序遍历的模版方法中加入左叶子节点的判断逻辑即可
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if(root==null){
return 0;
}
ArrayDeque<TreeNode> queue=new ArrayDeque();
queue.addLast(root);
int sum=0;
while(!queue.isEmpty()){
int size=queue.size();
for(int i=0;i<size;i++){
TreeNode node=queue.poll();
if(node.left!=null&&node.left.left==null&&node.left.right==null){
sum=sum+node.left.val;
}
if(node.left!=null){
queue.addLast(node.left);
}
if(node.right!=null){
queue.addLast(node.right);
}
}
}
return sum;
}
}