leetcode-889-105-106-根据前-中-后遍历构造二叉树


本题是leetcode,地址

889. 根据前序和后序遍历构造二叉树

105. 从前序与中序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树

题目

889. 根据前序和后序遍历构造二叉树

返回与给定的前序和后序遍历匹配的任何二叉树。

pre 和 post 遍历中的值是不同的正整数。

示例:

输入:pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]

提示:

1 <= pre.length == post.length <= 30
pre[] 和 post[] 都是 1, 2, ..., pre.length 的排列
每个输入保证至少有一个答案。如果有多个答案,可以返回其中一个。

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

105. 从前序与中序遍历序列构造二叉树

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/
9 20
/
15 7

106. 从中序与后序遍历序列构造二叉树

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

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/
9 20
/
15 7

分析

其实这三道题非常类似,做题的前提是需要了解树的前序遍历、中序遍历、后续遍历的特点;

  • 前序遍历:遍历顺序,根-左-右;第一个节点就是根节点;
  • 中序遍历:遍历顺序,左-根-右;根节点是区分左右子树的节点;
  • 后续遍历:遍历顺序,左-右-根;由此可知,根节点在最后;

[889. 根据前序和后序遍历构造二叉树]:

根据前序遍历和后序遍历特点,我们找到前序遍历中的第一个非根节点在第二个节点的位置,就可以分别分离出:前序遍历:(根)(左子树)(右子树)和 (左子树)(右子树)(根),这样我们便得到一个根节点,分别对左子树和右子树进行递归操作,也可以分别获取到其根节点,如此便可得到一颗完整的树;

同理我们可以分析出 前+中;中+后的推断逻辑;

一位网友概括如下:

前+后
首先我们可以显然知道当前根节点为pre[pre_start],并且它在后序中的位置为post_end,因此这里我们需要找到能区分左右子树的节点。
我们知道左子树的根节点为pre[pre_start+1],因此只要找到它在后序中的位置就可以分开左右子树(index的含义)
前+中
首先我们可以显然知道当前根节点为pre[pre_start],只用找出它在中序中的位置,就可以把左右子树分开(index的含义)
中+后
首先我们可以显然知道当前根节点为post[post_end],只用找出它在中序中的位置,就可以把左右子树分开(index的含义)

code

    // 889. 根据前序和后序遍历构造二叉树
    public TreeNode constructFromPrePost(int[] pre, int[] post) {
        if(pre==null || pre.length==0) {
            return null;
        }
        TreeNode root = new TreeNode(pre[0]);
        int length = pre.length;
        if(length == 1) {
            return root;
        }
        for(int index =0; index < length; index ++) {
            if(pre[1] == post[index]) {
                int[] pre_left = Arrays.copyOfRange(pre,1,index + 1 + 1);
                int[] pre_right = Arrays.copyOfRange(pre,index + 1 + 1 ,length);

                int[] post_left = Arrays.copyOfRange(post,0,index);
                int[] post_right = Arrays.copyOfRange(post,index + 1, length -1);

                root.left = constructFromPrePost(pre_left,post_left);
                root.right = constructFromPrePost(pre_right,post_right);
                break;
            }
        }
        return root;
    }


   // 105. 从前序与中序遍历序列构造二叉树
	 public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder == null || preorder.length == 0) {
            return null;
        } 
       
        int length = preorder.length;  
        TreeNode root =  new TreeNode(preorder[0]);
        if(length == 1) {
            return root;
        }

        for(int index = 0; index < length; index ++) {
            if(root.val == inorder[index]) {
                int[] preorder_left = Arrays.copyOfRange(preorder,1,index + 1);
                int[] preorder_right = Arrays.copyOfRange(preorder,index + 1, length);

                int[] inorder_left =  Arrays.copyOfRange(inorder,0,index);
                int[] inorder_right = Arrays.copyOfRange(inorder,index + 1,length);

                root.left = buildTree(preorder_left,inorder_left);
                root.right = buildTree(preorder_right,inorder_right);
                break;
            }
        }
        return root;
    }	



   // 106. 从中序与后序遍历序列构造二叉树
   public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder == null || postorder.length == 0) {
            return null;
        }
        
        int length = postorder.length;
        if(length == 1){
             return new TreeNode(postorder[length -1]);
        }

        TreeNode root = new TreeNode(postorder[length - 1]);
        for(int index = 0; index < length; index ++) {
            if(postorder[length -1] == inorder[index]) {
                int[] inorder_left = Arrays.copyOfRange(inorder,0,index);
                int[] inorder_right = Arrays.copyOfRange(inorder,index + 1,length);

                int[] postorder_left = Arrays.copyOfRange(postorder,0,index);
                int[] postorder_right = Arrays.copyOfRange(postorder,index,length -1);

                root.left = buildTree(inorder_left,postorder_left);
                root.right = buildTree(inorder_right,postorder_right );
                break;
            }
        }

        return root;
    }

你的鼓励也是我创作的动力

打赏地址

posted @ 2020-07-21 21:49  Yangsc_o  阅读(188)  评论(0编辑  收藏  举报