(Java)构造二叉树OJ题(LeetCode105 根据前序与中序构造二叉树,LeetCode106 根据后序与中序构造二叉树)

简介: 从前序遍历可以得到根结点,从中序中可以得到跟结点的左右子树部分,我们在构造二叉树的时候是从前序找根,再在中序中找根的左右子树部分先创建根节点再分别创建跟的左子树与跟的右子树,这个过程是一个递归,每次递归都要确定在中序哪个区间找新的根。

1. 根据前序与中序构造二叉树

根据前序与中序遍历构造二叉树


题目:给定一棵树的前序遍历 preorder 与中序遍历 inorder,请构造二叉树并返回其根节点 。


例如:

image.png


可以点开上述链接查看题目,具体做法如下:


分析:从前序遍历可以得到根结点,从中序中可以得到跟结点的左右子树部分,我们在构造二叉树的时候是从前序找根,再在中序中找根的左右子树部分先创建根节点再分别创建跟的左子树与跟的右子树,这个过程是一个递归,每次递归都要确定在中序哪个区间找新的根。


注意:前序顺序是根---左---右,所以还原的时候是根---左---右,这样才使得index++成立,index为标记前序的根,index从前序的开始依次走向末尾


具体步骤:


1. 在前序遍历中找根


2. 在中序遍历找根,用pos标记分界点,pos的左右两部分为递归找左与递归找右


3. 先还原根结点,再递归还原根的左子树,递归还原根的右子树


4. 递归还原的时候是依据中序遍历划分的范围


参考代码:

class Solution {
    int index = 0;  //标记前序的根
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return reBuildTree(preorder,inorder,0,inorder.length);
    }
    public TreeNode reBuildTree(int[] preorder,int[] inorder,int left,int right){
        //递归返回条件
        if(index>=preorder.length || left>=right){
            return null;
        }
        int pos = left;
        //在中序中找根的位置
        while(pos < right){
            if(inorder[pos] == preorder[index]){
                break;
            }
            pos++;
        }
        TreeNode root = new TreeNode(preorder[index]);//还原根
        index++;
        root.left = reBuildTree(preorder,inorder,left,pos);//递归还原左
        root.right = reBuildTree(preorder,inorder,pos+1,right);//递归还原右
        return root;
    }
}


2. 根据后序与中序构造二叉树

根据后序与中序构造二叉树


题目:根据一棵树的中序遍历与后序遍历构造二叉树。


例如:

image.png



可以点开上述链接查看题目,具体做法如下:


分析:后序遍历可以确定根结点,中序遍历可以得到根结点的左右子树两部分,所以还在中序遍历中找根节点的位置,用pos标记,将中序遍历分为两个部分,再分别在这两个部分中递归构造根的左子树与根的右子树。


注意:后续遍历是左---右---根,所以我们在还原的时候倒着还原,还原顺序为:根---右---左,这样使得index--成立,index为标记后续的根,它从后续的末尾依次走向开始


具体步骤:


1. 从后续遍历中找到根


2. 在中序中找到根的位置,用pos标记将中序遍历分为两部分


3. 在pos标记的右部分递归还原根的右子树


4. 在pos标记的左部分递归还原根的左子树


参考代码:

class Solution {
    int index;  //标记后序遍历的根
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        index = postorder.length-1; //后续的根
        return reBuildTree(inorder,postorder,0,inorder.length);
    }
    public TreeNode reBuildTree(int[] inorder,int[] postorder,int left,int right){
        //递归返回条件
        if(index < 0 || left >= right){
            return null;
        }
        //在中序遍历中找到根的位置
        int pos = left;
        while(pos < right){
            if(postorder[index] == inorder[pos]){
                break;
            }
            pos++;
        }
        //还原根
        TreeNode root = new TreeNode(postorder[index]);
        index--;
        root.right = reBuildTree(inorder,postorder,pos+1,right); //还原根的右
        root.left = reBuildTree(inorder,postorder,left,pos);  //还原根的左
        return root;
    }
}




相关文章
|
1月前
|
Java
java代码优化:判断内聚到实体对象中和构造上下文对象传递参数
通过两个常见的java后端实例场景探讨代码优化,代码不是优化出来的,而是设计出来的,我们永远不可能有专门的时间去做代码优化,优化和设计在平时
32 15
|
4月前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
39 2
|
4月前
【LeetCode 29】226.反转二叉树
【LeetCode 29】226.反转二叉树
36 2
|
4月前
【LeetCode 28】102.二叉树的层序遍历
【LeetCode 28】102.二叉树的层序遍历
27 2
|
4月前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
42 1
|
4月前
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
37 1
|
3月前
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
35 0
|
4月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
33 0
|
4月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
30 0
|
4月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
33 0