LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)

Posted 几米空间

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)相关的知识,希望对你有一定的参考价值。

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

 


题目标签:Array, Tree

  题目给了我们preOrder 和 inOrder 两个遍历array,让我们建立二叉树。先来举一个例子,让我们看一下preOrder 和 inOrder的特性。

 

                          1

                         /  \\

                        2            5

                          /      \\       /     \\

                                                 3         4   6        7

 

  preOrder: 1 2 3 4 5 6 7   遍历顺序为:print, left, right

       inOrder: 3 2 4 1 6 5 7     遍历顺序为: left, print, right 

  可以发现,preOrder的第一个肯定为root, 接下来都是左边的children, 在后面都是右边的children;

       inOrder的root在最中间,root左边的都是left children, root 右边的都是 right children。

 

  所以,我们可以建立一个递归helper function来帮助建立二叉树,把root 传递给 helper function, 让helper function 递归每一个root, 并且建立每一个root的left 和right child;

  其中的规律就是遍历preOrder array,

  从 preOrder 里拿到root点,对于每一个点: 有一个范围,来判断是不是走到最底端走完了,如果走完了就return,没走完就继续;

                       然后利用inOrder里的位置关系,来找到这个root点的 left child 和right child;

                       还要缩小这个范围,如果是left child, 那么就在inOrder里缩小到左边去,如果是right child,那么就在inOrder里缩小到右边去。

 

  举例:拿到1的话,设1为一个点,初始范围为inOrder position [0, 6] 接着要找到它的left child 和 right child;

     1的left -   preOrder中1的下一个数字2, 范围缩小到inOrder position [0, 2],2在其中,设2为1的left, 递归2;

     2的left -   preOrder中2的下一个数字3, 范围缩小到inOrder position [0, 0],3在其中,设3为2的left, 递归3;

     3的left -   preOrder中3的下一个数字4, 范围缩小到inOrder position [0, -1],意味着走到底端了,返回到2;(3的right同理)

     2的right - preOrder中3的下一个数字4, 范围缩小到inOrder position [2, 2],4在其中,设4为2的right,递归4;

     4的left -   preOrder中4的下一个数字5, 范围缩小到inOrder position [2, 1],意味着走到底端了,返回到2 (4的right同理);

     2的left right 都有了,所以继续返回到1;

     1的right - preOrder中4的下一个数字5, 范围缩小到InOrder position [4, 6],5在其中,设5为1的right, 递归5;

     5的left -   preOrder中5的下一个数字6, 范围缩小到inOrder position [4, 4],6在其中,设6为5的left, 递归6;

     6 走到底端,返回到5;

     5的right - preOrder中6的下一个数字7, 范围缩小到inOrder position [6, 6],7在其中,设7为5的right, 递归7;

     7 走到低端,返回5;

     5 left right 都有,返回1;

     1 返回自己,结束。

 

  具体细节请看code。

 

Java Solution:

Runtime beats 82.84% 

完成日期:08/26/2017

关键词:Array, Tree

关键点:递归;利用pre-order 和 in-order 的位置关系递归

 

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution 
11 {
12     public TreeNode buildTree(int[] preorder, int[] inorder) 
13     {
14         Map<Integer, Integer> inMap = new HashMap<Integer, Integer>();
15         
16         // save inorder number as key, position as value into map
17         for(int i=0; i<inorder.length; i++)
18             inMap.put(inorder[i], i);
19         
20         
21         TreeNode root = helper(preorder, 0, 0, inorder.length - 1, inMap);
22         
23         return root;    
24     }
25     
26     public TreeNode helper(int[] preorder, int preStart, int inStart, int inEnd, 
27             Map<Integer, Integer> inMap)
28     {
29         if(inStart > inEnd)
30             return null;
31         
32         int rootVal = preorder[preStart];
33         TreeNode root = new TreeNode(rootVal);
34         int inRoot = inMap.get(rootVal);  // position in inOrder
35         
36         /* inStart & inEnd: for left child, move inEnd to the left of root
37          *                  for right child, move inStart to the right of root */
38         root.left = helper(preorder, preStart + 1, inStart, inRoot - 1, inMap);
39         /* preStart: for right child, go to inorder to check how many left children does root have,  
40          * add it into preorder to skip them to reach right child */
41         root.right = helper(preorder, preStart + (inRoot - inStart) + 1, inRoot + 1, inEnd, inMap);
42         
43         return root;
44     }
45 }

参考资料:

https://discuss.leetcode.com/topic/3695/my-accepted-java-solution

 

 

LeetCode 算法题目列表 - LeetCode Algorithms Questions List

             

以上是关于LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-105-Construct Binary Tree from Preorder and Inorder Traversal

一天一道LeetCode#105. Construct Binary Tree from Preorder and Inorder Traversal

LeetCode OJ 105. Construct Binary Tree from Preorder and Inorder Traversal

leetcode 105 Construct Binary Tree from Preorder and Inorder Traversal ----- java

leetcode105:Construct Binary Tree from Preorder and Inorder Traversal

LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal