剑指offer——二叉树

重构二叉树(中等)

题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路分析:
前序遍历:从根节点开始,先访问根节点,然后左子树,再右子树;中序遍历:先左子树,再根节点,最后右子树;
所以前序数组的第一个元素一定是根节点,在中序数组中找到根节点的位置,此时在中序数组中根节点左边的是根节点的左子树的中序数组,右边则是根节点右子树的中序数组,采用递归方式则可继续分解确定每一个“根节点”
算法思想:

  1. 根据前序序列第一个结点确定根结点
  2. 根据根结点在中序序列中的位置分割出左右两个子序列
  3. 对左子树和右子树分别递归使用同样的方法继续分解
    在这里插入图片描述
import java.util.Arrays;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        //特判,空树
        if(pre.length==0 || in.length==0){
            return null;
        }
        TreeNode root=new TreeNode(pre[0]);//创建一个根节点
        //在in中找到根节点
        for(int i=0;i<in.length;i++){
            if(in[i]==pre[0]){
                //左子树,注意Arrys.copyOfRange为左闭右开空间
                root.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1,1+i),Arrays.copyOfRange(in,0,i));
                root.right=reConstructBinaryTree(Arrays.copyOfRange(pre,1+i,pre.length),Arrays.copyOfRange(in,i+1,in.length));
                //下次递归进入for循环,因此找完左右子树后就要结束整个循环。
                break;
            }
            
        }
        return root;
    }
}

树的镜像

题目: 操作给定的二叉树,将其变换为源二叉树的镜像。
在这里插入图片描述
**思路分析:**使用递归的思想,明确递归的结束条件,和调用自己的条件;
(1)当root为空时,直接结束当前函数
(2)当前root的左节点和右节点交换
(3)从左子树开始使用同样的逻辑开始递归;从右子树开始使用同样的逻辑递归.

public class Solution {
    public void Mirror(TreeNode root) {
        if(root==null)return;
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        if(root.left!=null){
            Mirror(root.left);
        }
        if(root.right!=null){
            Mirror(root.right);
        }
    }
}

求树的深度(简单)

解题思路

  • 如果树只有一个结点,它的深度为1。
  • 如果根结点只有左子树而没有右子树, 那么树的深度应该是其左子树的深度加1,同样如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1。
  • 如果既有右子树又有左子树, 那该树的深度就是其左、右子树深度的较大值再加1。
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root==null)return 0;
        int left = TreeDepth(root.left);
        int right = TreeDepth(root.right);
        return Math.max(left,right)+1;  
    }
}

树的平衡性检测(中等)

题目描述: 给定一颗树,判断其是否为平衡二叉树
**思路分析 :**平衡二叉树的定义:树的左右两个子树的高度差的绝对值不超过 1,并且 左右两个子树都是一棵平衡二叉树,空树也是一颗平衡二叉树。(解题思路就是这三个条件)
解题思路:

  1. 如果为空树,则返回true
  2. 此题是建立在求二叉树深度题目基础之上的,用getDepth()求当前树的左右子树的高度,判断其差的绝对值是否大于1
  3. 按照相同的判断逻辑,递归调用,判断这颗树的左子树、右子树是否均为平衡二叉树;
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        //如果root为null,则必为平衡二叉树
        if(root==null)return true;
        
        //判断当前树是否为平衡二叉树
        if(Math.abs(deep(root.left)-deep(root.right))>1){
            return false;
        }
        return IsBalanced_Solution(root.left)&&IsBalanced_Solution(root.right);
    }
    
    //求树的深度
    public int deep(TreeNode root){
        if(root==null)return 0;
        int left = deep(root.left);
        int right = deep(root.right);
        return Math.max(left,right)+1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值