110.平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
思路
根据平衡二叉树的定义,要判断一棵树是否平衡需要判断该树所有的子树是否平衡,只要有一棵子树不平衡,该树就不是平衡二叉树;
对于每一棵子树,要判断其是否平衡需要满足以下三个条件:
- 左子树是平衡二叉树;
- 右子树是平衡二叉树;
- 左右子树的高度差不超过1。
在进行递归遍历时,如果当前子树不是平衡二叉树,则返回-1;在计算左、右子树高度时,如果结果为-1,则意味着这棵树已经不是平衡二叉树了,不用再计算它的高度,返回-1即可。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return getDepth(root) == -1 ? false : true;
}
private int getDepth(TreeNode root){
if(root == null){
return 0;
}
int leftDepth=0,rightDepth=0;
leftDepth = getDepth(root.left);
if(leftDepth == -1){
return -1;
}
rightDepth = getDepth(root.right);
if(rightDepth == -1){
return -1;
}
return Math.abs(leftDepth - rightDepth) > 1 ? -1 : 1 + Math.max(leftDepth,rightDepth);
}
}
257. 二叉树的所有路径
给你一个二叉树的根节点
root,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
思路
要计算二叉树的路径,从根结点出发,到达叶子结点,遍历一定是从父结点到子结点的,因此,要采用中左右的前序遍历的方式进行。
参数:当前节点node,用于存储各路径的res,和当前路径path;
终止条件:如果终止条件落到null结点,那么路径将从叶子结点进入左孩子的null和右孩子的null,这条路径将被记录两次,不符合要求。因此,该算法的终止条件是当前结点是叶子结点。
过程:
- 当前结点加入路径中,如果当前结点有左孩子,则进入左孩子的路径中;如果当前结点有右孩子,则进入右孩子的路径中;
- 当路径遍历完成,将当前结果移出路径,因为使用同一个
path来标识路径,如果不移除当前结点,会对后续其他路径的记录产生影响。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
StringBuilder sb = new StringBuilder();
getPaths(root,res,sb);
return res;
}
private void getPaths(TreeNode node,List<String> res,StringBuilder path){
if(node.left == null && node.right == null){
// 到达叶子结点
// 将叶子结点加入到路径中
int length = path.length();
path.append("->");
path.append(node.val);
// 一条路径遍历完成
res.add(new String(path.substring(2)));
// 回退
path.delete(length,path.length());
return;
}
int length = path.length();
path.append("->");
path.append(node.val);
if(node.left != null){
getPaths(node.left,res,path);
}
if(node.right != null){
getPaths(node.right,res,path);
}
// 回退
path.delete(length,path.length());
}
}
404.左叶子之和
给定二叉树的根节点
root,返回所有左叶子之和。
思路
对于二叉树上的一个节点,
- 如果它的左孩子存在,且这个左孩子是一个叶子结点,那么这个节点的左叶子之和为 左孩子的值 + 右子树的左叶子之和;
- 如果它的左孩子不是叶子节点,那么这个节点的左叶子之和为 左子树的左叶子之和 + 右子树的左叶子之和;
- 由此可见,深度遍历的遍历方式应该是左右中的后序遍历。
- 如果该节点为
null,则遍历到终止条件,该节点的左叶子之和为0。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
return getSumofLeftLeaves(root);
}
private int getSumofLeftLeaves(TreeNode node){
if(node == null){
return 0;
}
int leftSum=0,rightSum=0;
leftSum = getSumofLeftLeaves(node.left);
rightSum = getSumofLeftLeaves(node.right);
if(node.left!=null && node.left.left==null && node.left.right==null){
return rightSum + node.left.val;
}
return leftSum + rightSum;
}
}