110.平衡二叉树
-
题目链接:代码随想录
-
区分两个概念:二叉树的深度和高度
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。 适合前序遍历
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。 适合后序遍历
对于本题来说:其实是求的根节点的高度,而根节点的高度就是这棵树的最大深度,所以才可以使用后序遍历。
- 解题思路:
1.参数:当前传入节点。 返回值:以当前传入节点为根节点的树的高度。用返回-1来标记不满足平衡二叉树
2.终止条件:遇到空节点返回0
3.判断逻辑:
如果左子树高度或者右子树高度提前为-1,那么说明一边不满足平衡二叉树,因此直接返回-1即可
如果遍历的左子树和右子树符合平衡二叉树的条件返回他们两个的最大值并且 + 1;
public boolean isBalanced(TreeNode root) {
return getHeight(root) != -1;
}
public int getHeight(TreeNode root){
if(root == null){
return 0;//终止条件
}
int leftHeight = getHeight(root.left);//这里直接定义,定义的是每一层的高度,一层一个变量
if(leftHeight == -1) return -1;//已经是不平衡树了,就返回-1
int rightHeight = getHeight(root.right);
if(rightHeight == -1) return -1;//已经是不平衡树了,就返回-1
//当成判断是否为平衡二叉树的逻辑
if(Math.abs(leftHeight - rightHeight) > 1){
return -1;
}
//遍历到结尾了
return Math.max(leftHeight, rightHeight) + 1;
}
257. 二叉树的所有路径
题目链接:代码随想录
-
前序遍历原因
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。 -
解题思路:
①设置变量:path变量用来存储路径值,res存出结果集
②参数和返回值:遍历过程中需要传入当前处理结点,和要存储到的路径信息,因此需要三个参数
数据都存储在固定变量中,不需要返回值
③终止条件:遍历到叶子结点,加入路径集,结束本次递归,返回上一层回溯
④处理逻辑:如果本层不是叶子结点,那么就先递归左面的子树,找寻叶子结点,找到之后移除数据回溯,
然后递归右面的子树
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<String>();
//特殊情况
if(root == null){
return res;
}
List<Integer> path = new ArrayList<>();//始终就一个值
traversal(root, path, res);
return res;
}
//每次只对相应元素进行判断修改,因此返回值为void
public void traversal(TreeNode root,List<Integer> path,List<String> paths){
path.add(root.val);//每次先放进来值,避免没有放进去叶子节点的值
if(root.left == null && root.right == null){//叶子结点,进行放值
StringBuilder sb = new StringBuilder();
for (int i = 0; i < path.size() - 1; i++) {
sb.append(path.get(i).toString()).append("->");
}
sb.append(path.get(path.size() - 1).toString());
paths.add(sb.toString());
return;//放回上一层
}
//对左右节点进行遍历
if(root.left != null){//确保不会空指针异常
traversal(root.left, path, paths);
path.remove(path.size() - 1);//回溯
}
if(root.right != null){//确保不会空指针异常
traversal(root.right, path, paths);
path.remove(path.size() - 1);
}
}
404.左叶子之和
题目链接:代码随想录
-
本题又是一道求和的题,采取后序遍历较为合适
-
这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。
此时就要通过节点的父节点来判断其左孩子是不是左叶子了。
平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。 -
解题思路:
①主要是求左叶子结点的和
②处理逻辑:如果找到下一层的左叶子结点,那么本层记录下此值,并加上,然后返回值即可
③终止条件为:遍历的节点为null时,说明遍历到头了
public int sumOfLeftLeaves(TreeNode root) {
if(root == null){
return 0;
}
int leftSum = sumOfLeftLeaves(root.left);
int rightSum = sumOfLeftLeaves(root.right);
int minSum = 0;
//判断是否为左节点的条件
if(root.left != null && root.left.left == null && root.left.right == null){
minSum = root.left.val;
}
return minSum + leftSum + rightSum;//中间的值
}