10.平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
返回 false 。
解答: 这个题主要通过后序遍历计算每个节点的高度来判断是不是高度差大于一,大于一说明不是平衡二叉树,返回-1即可
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
if(countBalance(root) == -1) return false;
return true;
}
private int countBalance(TreeNode root){
if(root == null) return 0;
int left, right;
left = countBalance(root.left);
if(left == -1) return -1;
right = countBalance(root.right);
if(right == -1) return -1;
int result = (int)Math.abs(left - right);
if(result > 1) return -1;
else{ return 1 + Math.max(left,right);}
}
}
257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
#算法公开课
《代码随想录》算法视频公开课 (opens new window)::递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径 (opens new window),相信结合视频在看本篇题解,更有助于大家对本题的理解。
解题: 这个题用到回溯的思想,回溯的难点主要是,我们要在遍历的下面写上回溯, 也就是我们每一个遍历开始之后,当返回到这里的时候就是回溯到这里了,这时候处理回溯的代码.
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<>();
List<Integer> paths = new ArrayList<>();
traverse(root,result,paths);
return result;
}
private void traverse(TreeNode root, List<String> result, List<Integer> paths){
//前序遍历法
paths.add(root.val);
//如果遇到叶子
if(root.left == null && root.right == null){
//把所有的路径写入到结果中
StringBuilder sb = new StringBuilder();
for(int i = 0; i < paths.size()-1; i++){
sb.append(paths.get(i));
sb.append("->");
}
sb.append(paths.get(paths.size() - 1));
result.add(sb.toString());
}
//左序遍历,遍历的同时注意回溯,注意判断是否为null
if(root.left != null){
traverse(root.left,result,paths);
paths.remove(paths.size() - 1);
}
//右序遍历,遍历的同时注意回溯,注意判断是否为null
if(root.right != null){
traverse(root.right,result,paths);
paths.remove(paths.size() - 1);
}
}
}
404.左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
#算法公开课
《代码随想录》算法视频公开课 (opens new window)::二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和 (opens new window),相信结合视频在看本篇题解,更有助于大家对本题的理解。
#思路
首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。
因为题目中其实没有说清楚左叶子究竟是什么节点,那么我来给出左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点
大家思考一下如下图中二叉树,左叶子之和究竟是多少?
其实是0,因为这棵树根本没有左叶子!
但看这个图的左叶子之和是多少?
相信通过这两个图,大家对最左叶子的定义有明确理解了。
那么判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。
如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:
if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
左叶子节点处理逻辑
}
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
//首先理解什么是左叶子,是上一个点左孩子不为空,然后
//这个左孩子左右都为空
if(root == null) return 0;
int left = sumOfLeftLeaves(root.left);
int right = sumOfLeftLeaves(root.right);
int mid = 0;
if(root.left != null && root.left.left == null && root.left.right == null){
mid = root.left.val;
}
int sum = mid + left + right;
return sum;
}
}