Construct Binary Tree from Preorder and Inorder Traversal medium
Problem Statement
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 binary 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] Input: [-1]
Steps and Explanation
The key to solving this problem lies in understanding the properties of preorder and inorder traversals:
- Preorder Traversal: The first element in
preorder
is always the root of the tree. - Inorder Traversal: In
inorder
, elements to the left of the root are in the left subtree, and elements to the right are in the right subtree.
We can use a recursive approach:
- Base Case: If the
preorder
array is empty, returnnull
. - Find the Root: The first element of
preorder
is the root. - Find the Root in Inorder: Locate the root in the
inorder
array. This index splits theinorder
array into left and right subtrees. - Recursive Calls: Recursively call the function to construct the left and right subtrees using the appropriate portions of
preorder
andinorder
. - Construct the Node: Create a new tree node with the root value and attach the left and right subtrees.
Code
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
}
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
if (preorder.length === 0) {
return null;
}
const rootVal = preorder[0];
const root = new TreeNode(rootVal);
const rootIndexInInorder = inorder.indexOf(rootVal);
// Construct left and right subtrees recursively
root.left = buildTree(preorder.slice(1, rootIndexInInorder + 1), inorder.slice(0, rootIndexInInorder));
root.right = buildTree(preorder.slice(rootIndexInInorder + 1), inorder.slice(rootIndexInInorder + 1));
return root;
}
Complexity
- Time Complexity: O(N), where N is the number of nodes in the tree. This is because we visit each node once during the recursive calls.
- Space Complexity: O(N) in the worst case (a skewed tree), due to the recursive call stack. In the average case, it's O(log N) for a balanced tree. There's also O(N) space used for the
preorder
andinorder
array copies in the recursive calls, though this could be optimized to O(1) by passing indices instead of slicing arrays.