[LeetCode] 105. Construct Binary Tree from Preorder and Inorder Traversal

Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.

Example 1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

Example 2:

Input: preorder = [-1], inorder = [-1]
Output: [-1]

Constraints:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder and inorder consist of unique values.
  • Each value of inorder also appears in preorder.
  • preorder is guaranteed to be the preorder traversal of the tree.
  • inorder is guaranteed to be the inorder traversal of the tree.

从前序与中序遍历序列构造二叉树。

题意是给一个二叉树的前序遍历和中序遍历,请根据这两个遍历,把树构造出来。你可以假设树中没有重复的元素。

思路是递归 + 分治。首先,preorder 的首个元素是树的根节点 root。然后在中序遍历中找到这个根节点的位置,在其左边的所有元素会构成其左子树,在其右边的元素会构成其右子树。

还是跑这个例子,

preorder = [3,9,20,15,7] - 3是根节点

inorder = [9,3,15,20,7] - 9是左子树节点;15,20,7会构成右子树

preorder 中,第一个节点 3 是根节点,之后的节点是先列出所有的左孩子(黄色),再列出所有的右孩子(蓝色)。在 inorder 的排列中位于 3 之前的所有元素应该是左孩子;位于 3 之后的元素应该是右孩子。代码中的 index 变量,找的是根节点在 inorder 里面的坐标。

根据如上的结论,再下一轮递归调用的时候你会发现 20 是 3 的右孩子,而 15 和 7 分别是 20 的左孩子和右孩子。其他步骤参见代码注释。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public TreeNode buildTree(int[] preorder, int[] inorder) {
 3         if (preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0
 4                 || preorder.length != inorder.length) {
 5             return null;
 6         }
 7         return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
 8     }
 9 
10     private TreeNode helper(int[] preorder, int pStart, int pEnd, int[] inorder, int iStart, int iEnd) {
11         //递归的第一步:递归终止条件,避免死循环
12         if (pStart > pEnd || iStart > iEnd) {
13             return null;
14         }
15         //重建根节点
16         TreeNode root = new TreeNode(preorder[pStart]);
17         int index = 0; //index找到根节点在中序遍历的位置
18         while (inorder[iStart + index] != preorder[pStart]) {
19             index++;
20         }
21         //重建左子树
22         root.left = helper(preorder, pStart + 1, pStart + index, inorder, iStart, iStart + index - 1);
23         //重建右子树
24         root.right = helper(preorder, pStart + index + 1, pEnd, inorder, iStart + index + 1, iEnd);
25         return root;
26     }
27 }

 

相关题目

105. Construct Binary Tree from Preorder and Inorder Traversal

106. Construct Binary Tree from Inorder and Postorder Traversal

889. Construct Binary Tree from Preorder and Postorder Traversal

1008. Construct Binary Search Tree from Preorder Traversal

LeetCode 题目总结

posted @ 2020-04-21 12:13  CNoodle  阅读(663)  评论(0编辑  收藏  举报