1.平衡二叉树
110. 平衡二叉树 - 力扣(Leetcode)https://leetcode.cn/problems/balanced-binary-tree/题目描述:
左子树和右子树的深度超过1那就不是平衡二叉树
例如:
题解:使用递归思路
🧐思路:写一个方法 getHeight() 使用递归的方式求树的高度,如果左右子树高度差为大于1时不为平衡二叉树就返回-1,<= 1时就正常返回树的高度,在主方法中返回 getHeight(root) 的返回值是否大于等于0即可。
先来讲一下求树高度的思路:
先定义一个变量 leftTree 为左子树的高度,左子树为根节点一直递进,如果为null返回0归出,然后定义变量 rightTree 为右子树高度,将右子树为根节点一直递进,为null返回0归出,然后返回左右子树高度最大的那一个 +1 的值。
代码:
public int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
int leftTree = getHeight(root.left);
int rightTree = getHeight(root.right);
return Math.max(leftTree,rightTree) + 1;
}
}
示例:
画图描述:
在求树高度的基础上在加上判断条件 如果左右子树高度差为大于1时不为平衡二叉树就返回-1,<= 1时就正常返回树的高度
画图演示:
这个判断的前提是在递进全部归出,已经到根结点时,如果我们还没归出到根节点的位置,而是在中途就发现左右子树不平衡了,那么后续就不需要再去比较左右节点的高度差值,我们需要额外加一个条件,判断我们的 leftTree 和 rightTree 是否为-1,是-1代表已经发现不是平衡树了,继续返回-1即可。
代码:
public boolean isBalanced(TreeNode root) {
return getHeight(root) >= 0;
}
public int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
int leftTree = getHeight(root.left);
int rightTree = getHeight(root.right);
if(Math.abs(leftTree - rightTree) > 1 || leftTree == -1 || rightTree == -1) {
return -1;
}else {
return Math.max(leftTree,rightTree) + 1;
}
}
2.另一棵树的子树
572. 另一棵树的子树 - 力扣(Leetcode)https://leetcode.cn/problems/subtree-of-another-tree/description/题目描述:
题解:递归
🧐思路:使用前序遍历的递归思路,root从根节点开始和 subRoot 比较,然后从 root.left 左子树为根节点开始和 subRoot 进行比较,直到比较出 subRoot 是 root 的子树时停止,不然就使用前序的思路将 root 的每一个节点都当做根节点去和 subRoot比较。
比较又是如何比较的呢❓
此时我们定义一个方法来判断:
1. root 和 subRoot 都为空的情况下返回 true。
2. root 和 subRoot 有一方为空一方不为空返回 false。
3. root 和 subRoot 都不为空,此时判断双方的 val 值是否相等,不相等返回 false,相等进行递归,返回(将双方左子树传参递进 && 双方右子树传参递进)的值,即双方都为 true 才能返回 true。
画图描述:
代码:
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
//这里注意,当传进来的root是null时,必须返回false
//否则会报空指针异常,因为他会继续传root.left进行递进
//当传进来的root是null时,null和subRoot进行判断也不可能是true
if(root == null) {
return false;
}
//这里使用按位或,当isSameTree 判断为true时,按位或后面的表达式可以不用进行计算
return isSameTree(root,subRoot) || isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot);
}
public boolean isSameTree(TreeNode root, TreeNode subRoot) {
if(root == null && subRoot != null || root != null && subRoot == null) {
return false;
}
if(root == null && subRoot == null) {
return true;
}
if(root.val != subRoot.val) {
return false;
}
return isSameTree(root.left,subRoot.left) && isSameTree(root.right,subRoot.right);
}
3.对称二叉树
101. 对称二叉树 - 力扣(Leetcode)https://leetcode.cn/problems/symmetric-tree/description/题目描述:
题解:递归
🧐思路:查看是否对称,首先肯定是要查看对应的左右子树是否相等,如示例中第三层,左边val 值为3的左子树为val 值为2的左子树,右边val 值为3的右子树为val 值为2的右子树,首先定义一个方法isSymmetricChild() 判断左右子树是否相等,参数为 leftTree 和 rightTree, 第一次传参为根结点的左子树和右子树,递归时我们需要传入当前 leftTree 和rightTree 的相反子树,例如 leftTree的左子树和 rightTree 的右子树,leftTree 的右子树和 rightTree 的左子树。
知道了比较的对象后,我们还要思考如何去比较是否对称呢,给出三个条件:
① lefTree 和 rightTree 都为null 的情况下,肯定是不影响对称的因素,直接返回 true
② leftTree 和 rightTree 只有一方为null 时,那下肯定不是轴对称的,直接返回false
③ leftTree 和 rightTree 都不为null 时,我们去判断他的val 值是否相等,不相等返回 flase,相等我们将递归进当前 leftTree 和rightTree 的相反子树,直到满足上方俩个条件,即有一方为null 时或者都为null时开始归出。
画图描述:
代码:
public boolean isSymmetric(TreeNode root) {
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
if(leftTree == null && rightTree == null) {
return true;
}
if(leftTree == null||rightTree == null) {
return false;
}
if(leftTree.val != rightTree.val) {
return false;
}
return isSymmetricChild(leftTree.left,rightTree.right) &&
isSymmetricChild(leftTree.right,rightTree.left);
}
思路差不多的题
如果你看明白了这道题的思路,请独立思考并写出下面这道题。
100. 相同的树 - 力扣(Leetcode)https://leetcode.cn/problems/same-tree/submissions/397587475/
4.翻转二叉树
226. 翻转二叉树 - 力扣(Leetcode)https://leetcode.cn/problems/invert-binary-tree/description/
题解:使用递归
🧐思路:创建临时对象将结点的左右指向交换,然后递归左子树和右子树,最后返回根结点。
也可以先递归,然后再交换。
代码:
//先交换后递归
public TreeNode invertTree(TreeNode root) {
if(root == null) {
return null;
}
TreeNode curTree = root.left;
root.left = root.right;
root.right =curTree;
invertTree(root.left);
invertTree(root.right);
return root;
}
//先递归后交换
public TreeNode invertTree(TreeNode root) {
if(root == null) {
return null;
}
invertTree(root.left);
invertTree(root.right);
TreeNode curTree = root.left;
root.left = root.right;
root.right =curTree;
return root;
}