Construct Binary Tree from Preorder and Inorder Traversal - Complete Solution Guide
Construct Binary Tree from Preorder and Inorder Traversal is LeetCode problem 105, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
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 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 c
Detailed Explanation
The problem asks us to reconstruct a binary tree given its preorder and inorder traversals. Preorder traversal visits the root node first, then the left subtree, then the right subtree. Inorder traversal visits the left subtree, then the root node, then the right subtree. The input consists of two integer arrays, `preorder` and `inorder`, representing these traversals. The output should be the root of the constructed binary tree. The constraints ensure that the input is valid, including that the traversals represent the same tree, and the values are unique.
Solution Approach
The solution uses a recursive approach. The `preorder` array is used to determine the root node, and the `inorder` array is used to determine the structure of the left and right subtrees. We maintain an index into the `preorder` array to track the current root node. We also use a hash map to store the indices of each value in the `inorder` array. This allows us to quickly find the index of the root node in the `inorder` array, which is needed to determine the size of the left and right subtrees. The recursive function `build` is then called to construct the left and right subtrees, using the appropriate subarrays of the `preorder` and `inorder` arrays.
Step-by-Step Algorithm
- Step 1: Check for an empty input. If either `preorder` or `inorder` is empty, return `null` (or `nullptr` in C++, `NULL` in C).
- Step 2: Create a hash map (`inorder_map`) to store the indices of each value in the `inorder` array. This allows for O(1) lookup of the index of a value in the `inorder` array.
- Step 3: Initialize a `preorder_index` to 0. This variable will keep track of the next root value in the `preorder` array.
- Step 4: Define a recursive function `build(in_left, in_right)`. This function takes the left and right indices of the current subarray of the `inorder` array as input.
- Step 5: In the `build` function, check if `in_left > in_right`. If so, it means there are no more nodes in the current subtree, so return `null`.
- Step 6: Create a new `TreeNode` with the value at `preorder[preorder_index]`. Increment `preorder_index`.
- Step 7: Find the index of the root value in the `inorder_map`. This is `inorder_root_index = inorder_map[root_val]`.
- Step 8: Recursively call `build` to construct the left subtree. The left subtree consists of the elements in the `inorder` array from `in_left` to `inorder_root_index - 1`. `root.left = build(in_left, inorder_root_index - 1);`
- Step 9: Recursively call `build` to construct the right subtree. The right subtree consists of the elements in the `inorder` array from `inorder_root_index + 1` to `in_right`. `root.right = build(inorder_root_index + 1, in_right);`
- Step 10: Return the newly created `root` node.
- Step 11: Call the `build` function with the initial range of the `inorder` array (0 to `inorder.length - 1`).
- Step 12: Return the result of the `build` function.
Key Insights
- Insight 1: The first element in the `preorder` array is always the root of the tree (or a subtree).
- Insight 2: The `inorder` array allows us to determine the structure of the left and right subtrees relative to the root. All elements to the left of the root value in the `inorder` array form the left subtree, and all elements to the right form the right subtree.
- Insight 3: Recursion is a natural fit for solving this problem because we can break down the problem of constructing the entire tree into smaller subproblems of constructing the left and right subtrees.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Array, Hash Table, Divide and Conquer, Tree, Binary Tree.
Companies
Asked at: Adobe, Apple, Bloomberg, Meta, Salesforce, Snowflake, Tesla, TikTok, Yahoo.