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