题目地址(105. 从前序与中序遍历序列构造二叉树)

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

题目描述

  1. 给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
  2. 示例 1:
  3. Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
  4. Output: [3,9,20,null,null,15,7]
  5. 示例 2:
  6. Input: preorder = [-1], inorder = [-1]
  7. Output: [-1]
  8. 提示:
  9. 1 <= preorder.length <= 3000
  10. inorder.length == preorder.length
  11. -3000 <= preorder[i], inorder[i] <= 3000
  12. preorder inorder 均无重复元素
  13. inorder 均出现在 preorder
  14. preorder 保证为二叉树的前序遍历序列
  15. inorder 保证为二叉树的中序遍历序列

前置知识


公司

  • 暂无

思路

image.png
image.png
知识点:

前序遍历列表:第一个元素永远是 【根节点 (root)】
中序遍历列表:根节点 (root)【左边】的所有元素都在根节点的【左分支】,【右边】的所有元素都在根节点的【右分支】
算法思路:

通过【前序遍历列表】确定【根节点 (root)】
将【中序遍历列表】的节点分割成【左分支节点】和【右分支节点】
递归寻找【左分支节点】中的【根节点 (left child)】和 【右分支节点】中的【根节点 (right child)】

关键点


代码

  • 语言支持:Java

Java Code:

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. public TreeNode buildTree(int[] preorder, int[] inorder) {
  18. return loop(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
  19. }
  20. public TreeNode loop(int[] preorder, int preLeft, int preRight,
  21. int[] inorder, int inLeft, int inRight) {
  22. //中止条件
  23. if (inLeft > inRight) {
  24. return null;
  25. }
  26. //找到根节点
  27. int rootVal = preorder[preLeft];
  28. TreeNode root = new TreeNode(rootVal);
  29. //找到中序序列中根节点的位置
  30. int index = 0;
  31. for (int i = inLeft; i <= inRight ; i++) {
  32. if (inorder[i] == rootVal) {
  33. index = i;
  34. break;
  35. }
  36. }
  37. //将原序列分割成左右两个子树
  38. int leftSize = index - inLeft;
  39. root.left = loop(preorder , preLeft+1 , preLeft +leftSize, inorder ,inLeft ,index-1);
  40. root.right = loop(preorder , preLeft + leftSize +1 , preRight, inorder ,index+1 ,inRight);
  41. return root;
  42. }
  43. }

复杂度分析

令 n 为数组长度。

  • 时间复杂度:105. 从前序与中序遍历序列构造二叉树 - 图3#card=math&code=O%28n%29&id=AeMoP)
  • 空间复杂度:105. 从前序与中序遍历序列构造二叉树 - 图4#card=math&code=O%28n%29&id=MGJwG)