题目

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

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

For example, given

  1. preorder = [3,9,20,15,7]
  2. inorder = [9,3,15,20,7]

Return the following binary tree:

  1. 3
  2. / \
  3. 9 20
  4. / \
  5. 15 7

题意

给定一棵二叉树的先序序列和中序序列,要求重建这棵二叉树。

思路

由二叉树的性质可知,先序序列的第一个元素是当前二叉树的根节点,根节点将中序序列分为左子树和右子树。先序序列的第一个元素即为整棵二叉树的根节点,在中序序列中找到该元素,则中序中该元素左侧为左子树,右侧为右子树,依照左右子树个数又可将先序序列剩余元素进行划分,接着只要对左子树和右子树进行递归操作即可。


代码实现

Java

  1. class Solution {
  2. public TreeNode buildTree(int[] preorder, int[] inorder) {
  3. // 为了省去在中序序列中迭代查找元素的时间, 直接用HashMap将整个inorder存进去
  4. Map<Integer, Integer> map = new HashMap<>();
  5. for (int i = 0; i < inorder.length; i++) {
  6. map.put(inorder[i], i);
  7. }
  8. return buildTree(map, preorder, 0, preorder.length - 1, 0, inorder.length - 1);
  9. }
  10. private TreeNode buildTree(Map<Integer, Integer> map, int[] preorder, int preI, int preJ, int inI, int inJ) {
  11. // 递归边界
  12. if (preI > preJ) {
  13. return null;
  14. }
  15. if (preI == preJ) {
  16. return new TreeNode(preorder[preI]);
  17. }
  18. // 在中序序列中找到先序序列的第一个元素,并求出左子树的长度
  19. int len = map.get(preorder[preI]) - inI;
  20. TreeNode root = new TreeNode(preorder[preI]);
  21. // 划分区域后递归处理左右子树
  22. root.left = buildTree(map, preorder, preI + 1, preI + len, inI, inI + len - 1);
  23. root.right = buildTree(map, preorder, preI + len + 1, preJ, inI + len + 1, inJ);
  24. return root;
  25. }
  26. }

JavaScript

  1. /**
  2. * @param {number[]} preorder
  3. * @param {number[]} inorder
  4. * @return {TreeNode}
  5. */
  6. var buildTree = function (preorder, inorder) {
  7. return construct(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1)
  8. }
  9. var construct = function (preorder, pa, pb, inorder, ia, ib) {
  10. if (pa > pb) return null
  11. const root = new TreeNode(preorder[pa])
  12. const leftLen = inorder.indexOf(root.val) - ia
  13. root.left = construct(preorder, pa + 1, pa + leftLen, inorder, ia, ia + leftLen - 1)
  14. root.right = construct(preorder, pa + leftLen + 1, pb, inorder, ia + leftLen + 1, ib)
  15. return root
  16. }