110.平衡二叉树
-
题意:给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
-
思路:
- 概念:
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。求深度适合用前序:中左右遍历
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。求高度适合用后序:左右中遍历
- 递归
-
参数:当前的传入节点;返回值:以当前传入节点为根节点的树的高度。
如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。
-
明确终止条件: 如果遇到空间点就终止,返回高度0。表示当前这个空节点的高度为0。
-
明确递归逻辑:分别求左右子树的高度,如果差值小于等于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) {
//如果返回的不是-1,那就是平衡二叉树。
return getHeight(root) != -1;
}
public int getHeight(TreeNode root) {
if(root == null) {
return 0;
}
//如果左子树为-1,则左子树就不是平衡二叉树了,直接往上返回-1
int leftHeight = getHeight(root.left);
if(leftHeight == -1) {
return -1;
}
//与左子树同理
int rightHeight = getHeight(root.right);
if(rightHeight == -1) {
return -1;
}
//如果左右子树都是平衡二叉树,看左右子树的高度差
if(Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}
//这个是每次来计算高度的,每次遍历高度变化在这个+1上
return Math.max(leftHeight, rightHeight) + 1;
}
}
257.二叉树的所有路径
- 257.二叉树的所有路径 | 题目链接
- 代码随想录 | 讲解链接
- 题意:给定一个二叉树,返回所有从根节点到叶子节点的路径。
- 思路
- 遍历顺序:前序遍历,是为了让父节点指向孩子节点
- 递归
- 递归函数参数及返回值:参数根节点,记录每一条路径的path,存放最终结果的res,递归不需要返回值
- 确定终止条件:传入节点的左右孩子都不为空
- 递归逻辑:前序遍历需首先处理中间节点,把传入节点的值放进path中;
左右孩子进行递归;
递归后做回溯,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<>();
if(root == null) {
return res;
}
List<Integer> path = new ArrayList<>();
traversal(root, path, res);
return res;
}
public void traversal(TreeNode root, List<Integer> path, List<String> res) {
path.add(root.val); //前序遍历,把中间节点加入到一条路径path中
//遇到叶子节点,叶子节点的左右孩子都是null
if(root.left == null && root.right == null) {
//输出这条路径
StringBuilder sb = new StringBuilder(); //StringBuilder拼接字符串,速度更快
for(int i = 0; i < path.size() - 1; i++) {
sb.append(path.get(i)).append("->");
}
sb.append(path.get(path.size() - 1));//加上当前path中的最后一个节点
res.add(sb.toString()); //收集完一个路径把结果放到res中
return;
}
//递归和回溯是同时进行,所以要放在同一个花括号里
if(root.left != null) { //左孩子不为null时,把左孩子放到path中
traversal(root.left, path, res);
path.remove(path.size() - 1); //回溯
}
if(root.right != null) { //右孩子不为null时,把右孩子放到path中
traversal(root.right, path, res);
path.remove(path.size() - 1);
}
}
}
404.左叶子之和
-
题意:计算给定二叉树的所有左叶子之和。
-
思路:递归,但是要明确什么是左叶子,左叶子是左孩子不为空,但左孩子的左右孩子为null的节点。
/**
* 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) {
//遍历到空姐点,左叶子值一定为0;
if(root == null) {
return 0;
}
//后序遍历
int leftValue = sumOfLeftLeaves(root.left); //左,求左子树的左叶子之和
int rightValue = sumOfLeftLeaves(root.right); //右,求右子树的左叶子之和
int midValue = 0; //计算当前节点的左子树的和
//判断传入节点的左孩子是不是左叶子
//节点左孩子需不为空,但左孩子的左右孩子必须为空才是左叶子
//节点的左孩子是左叶子了,就把左孩子的值存起来。
if(root.left != null && root.left.left == null && root.left.right == null) {
midValue += root.left.val;
}
//当前节点的左孩子的值 + 左孩子子树的值 + 右孩子子树中左孩子的值
int res = midValue + leftValue + rightValue; //中
return res;
}
}