文章目录
- 前言
- 一、翻转二叉树(力扣226)
- 1、递归法
- 1、使用前序遍历
- 2、使用后序遍历
- 2、迭代法
- 1、层序遍历
- 二、对称二叉树(力扣101)
- 三、相同的树(力扣100)
- 四、另一棵树的子树(力扣572)
- 五、完全二叉树的结点个数(力扣222)
前言
1、翻转二叉树
2、对称二叉树
3、相同的树
4、另一棵树的子树
5、完全二叉树的结点个数
一、翻转二叉树(力扣226)
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
1、递归法
1、使用前序遍历
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return root;
TreeNode temp = root.left;
root.left=root.right;
root.right=temp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
2、使用后序遍历
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return root;
invertTree(root.left);
invertTree(root.right);
TreeNode temp = root.left;
root.left=root.right;
root.right=temp;
return root;
}
}
2、迭代法
1、层序遍历
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {return null;}
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
while (size-- > 0) {
TreeNode node = deque.poll();
swap(node);
if (node.left != null) {deque.offer(node.left);}
if (node.right != null) {deque.offer(node.right);}
}
}
return root;
}
public void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
二、对称二叉树(力扣101)
给定一个二叉树,检查它是否是镜像对称的。
前中后序只能采用后序遍历
判断左子树右子树是否可以翻转,并将结果返回给根节点
左为空 右不为空 return false
右为空 左不为空 return false
左为空 右为空 return true
左 右数值不相等 return false
左 右数值相等 进行递归判断下一层结点
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root!=null){
return true;
}
return Compare(root.left,root.right);
}
public boolean Compare(TreeNode left,TreeNode right){
//避免后续出现空指针的情况 所以先处理为空的条件
if(left==null && right!=null) return false;
else if(left!=null && right==null) return false;
else if(left==null && right==null) return true;
else if(left.val!=right.val) return false;
//左右“节点”都不为空 且数值相等的情况
//此时才进行递归 进行下一层判断
boolean outside = Compare(left.left,right.right);
boolean inside = Compare(left.right,right.left);
boolean isSame = outside && inside;
return isSame;
}
}
三、相同的树(力扣100)
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
思路:
与第二题一致
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null && q!=null) return false;
else if(p!=null && q==null) return false;
else if(p==null && q==null) return true;
else if(p.val!=q.val) return false;
//结点不为空且数值相等的情况
boolean leftside = isSameTree(p.left,q.left);
boolean rightside = isSameTree(p.right,q.right);
return leftside && rightside;
}
}
四、另一棵树的子树(力扣572)
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
思路:
将是否是子树的问题转化为是否相等的问题
判断两个树是否相等的三个条件(与的关系):
- 当前两个树的根节点值相等;
- 并且,s的左子树和t的左子树相等;
- 并且,s的右子树和t的右子树相等
判断t是否为s的子树的三个条件(或的关系): - 当前两棵树相等
- 或者,t是s的左子树
- 或者,t是s的右子树
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
return dfs(root,subRoot);
}
public boolean dfs(TreeNode root,TreeNode subRoot){
if(root==null) return false;
boolean check = isSame(root,subRoot);
boolean leftTree = dfs(root.left,subRoot);
boolean rightTree = dfs(root.right,subRoot);
return check || leftTree || rightTree;
}
public boolean isSame(TreeNode root, TreeNode subRoot){
if(root==null && subRoot==null) return true;
else if(root==null && subRoot!=null) return false;
else if(root!=null && subRoot==null) return false;
else if(root.val!=subRoot.val) return false;
//根节点不为空且数值相等
boolean left = isSame(root.left,subRoot.left);
boolean right = isSame(root.right,subRoot.right);
return left && right;
}
}
五、完全二叉树的结点个数(力扣222)
给出一个完全二叉树,求出该树的节点个数。
把完全二叉树当做一棵普通的二叉树
可以用前中后层序遍历去统计结点数目
class Solution {
public int countNodes(TreeNode root) {
//后序遍历
if(root==null)return 0;
int leftNum = countNodes(root.left);
int rightNum = countNodes(root.right);
return leftNum+rightNum+1;
}
}
利用完全二叉树特性
较难理解
class Solution {
public int countNodes(TreeNode root) {
//后序遍历
// if(root==null)return 0;
// int leftNum = countNodes(root.left);
// int rightNum = countNodes(root.right);
// return leftNum+rightNum+1;
//完全二叉树特性
if(root==null) return 0;
TreeNode leftNode = root.left;
TreeNode rightNode = root.right;
int leftDepth = getDepth(root.left);
int rightDepth = getDepth(root.right);
if(leftDepth==rightDepth){//说明是满二叉树
return (1 << leftDepth) + countNodes(root.right);
}else {// 右子树是满二叉树
return (1 << rightDepth) + countNodes(root.left);
}
}
private int getDepth(TreeNode root) {
int depth = 0;
while (root != null) {
root = root.left;
depth++;
}
return depth;
}
}