1. 程式人生 > 實用技巧 >leetcode-889-105-106-根據前-中-後遍歷構造二叉樹

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;
    }

你的鼓勵也是我創作的動力

打賞地址