105. Construct Binary Tree from Preorder and Inorder Traversal
这个我以前写过好几次了……把以前的粘上来吧
先序遍历的第一个数就是树的根,然后在中序遍历里面找到这个根的位置,它左边的就是左子树,右边的就是右子树,例如:
如果一个树的先序遍历结果是1245,中3687序是42516837。
那么它的跟就是1,用1把中序分成两半,左子树就是425,长度为3,右子树就是6837,长度为4。
再在先序中截出前三位,即为左子树的值,顺序为245,右子树是3687.
对于左子树,先序是245,中序是425,根是2,所以下一层左子树是4,右子树是5
对于右子树,先序是3687,中序是6837,根是3,所以下一层左子树是68,右子树是7
需要用HashMap存放inorder的值和位置,来切断左右子树。
过程:
主函数:
1. 检查null和length==0的情况
2. 建立一个HashMap,把inorder[i]作为key,i作为值存入
helper函数:
1. 如果inL>inR或者preL>preR,那么返回空
2. 找到根,即preorder[preL]在inorder里面的位置index
3. 给根的值创建一个节点
4. root.left = helper(preorder, preL+1, preL+index-inL, inorder, inL, index-1, map)
5. root.right = helper(preorder, preL+index-inL+1, preR, inorder, index+1, inR, map)
6. 返回root
1 public TreeNode buildTree(int[] preorder, int[] inorder) { 2 if(preorder.length == 0 || inorder.length != preorder.length) { 3 return null; 4 } 5 6 return helper(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1); 7 } 8 9 private TreeNode helper(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) { 10 if(preStart > preEnd || inStart > inEnd) { 11 return null; 12 } 13 TreeNode root = new TreeNode(preorder[preStart]); 14 int rootIndex = indexOf(inorder, preorder[preStart], inStart); 15 int leftLen = rootIndex - inStart; 16 int rightLen = inEnd - rootIndex; 17 root.left = helper(preorder, inorder, preStart + 1, preStart + leftLen, inStart, rootIndex - 1); 18 root.right = helper(preorder, inorder, preEnd - rightLen + 1, preEnd, rootIndex + 1, inEnd); 19 return root; 20 } 21 22 private int indexOf(int[] arr, int key, int start) { 23 for(int i = start; i < arr.length; i++) { 24 if(arr[i] == key) { 25 return i; 26 } 27 } 28 return -1; 29 }