重建二叉树Java(前序和中序+中序和后序)

一、根据前序和后序重建二叉树

输入某二叉树的前序遍历中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。LeetCode面试题07
例如,给出:

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:
在这里插入图片描述
【法一】:推荐方法

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        return dfs(pre,0,pre.length-1,in,0,in.length-1);
    }
    public TreeNode dfs(int [] pre,int preleft,int preright,int [] in,int inleft,int inright){
        if(preleft > preright || inleft> inright) { //当到达边界条件时候返回null
            return null;
        }
        //新建一个root
        TreeNode root= new TreeNode(pre[preleft])
        //对中序数组进行输入边界的遍历
        for(int i = inleft; i<= inright; i++){  
            if(pre[preleft] == in[i]){ //找出中序数组中父结点位置i
                //重构左子树,注意左子树的边界条件
                root.left = dfs(pre,preleft+1,preleft+i-inleft,in,inleft,i-1);//i-inleft为左子树节点数
                //重构右子树,注意右子树的边界条件
                root.right = dfs(pre,preleft+i+1-inleft,preright,in,i+1,inright);
            }
        }
        return pRootOfTree;     
    }
}

前序遍历左子树边界preleft+1 —— preleft + i - inleft中序遍历左子树边界inleft —— i-1

左右子树以root的位置i为届,右子树在左子树的基础上加上i - inleft

【法二】

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;
        int inLen = inorder.length;
        if(preLen == 0 && inLen == 0){
            return null;
        }
        TreeNode root = new TreeNode(preorder[0]);
        //找出中序遍历根节点下标
        int preRootIndex = -1;
        for(int i=0;i<inLen;i++){
            if(inorder[i] == preorder[0]){
                preRootIndex = i;
            }
        }
        int[] inLeftTree = Arrays.copyOfRange(inorder,0,preRootIndex);
        int[] inRightTree = Arrays.copyOfRange(inorder,preRootIndex+1,inLen);
        int[] preLeftTree = Arrays.copyOfRange(preorder,1,inLeftTree.length+1);
        int[] preRightTree = Arrays.copyOfRange(preorder,inLeftTree.length+1,preLen);

        root.left = buildTree(preLeftTree,inLeftTree);
        root.right = buildTree(preRightTree,inRightTree);
        return root;
    }
}

二、根据中序和后序重建二叉树

根据一棵树的中序遍历与后序遍历构造二叉树。
在这里插入图片描述

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return dfs(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
    }

    public TreeNode dfs(int[] inorder,int inleft,int inright,int[] postorder,int postleft,int postright){
        if(inleft > inright || postleft > postright){
            return null;
        }
        TreeNode root = new TreeNode(postorder[postright]);//root
        for(int i = inleft;i<=inright;i++){ //遍历中序数组
            if(postorder[postright] == inorder[i]){//找出中序数组中父结点的位置i
            	//重构左子树
                root.left = dfs(inorder,inleft,i-1,postorder,postleft,postleft+i-inleft-1);//左子树长i-inleft
                //重构右子树
                root.right = dfs(inorder,i+1,inright,postorder,postleft+i-inleft,postright-1);
            }
        }
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值