HomeLeetcode105. Construct Binary Tree from Preorder and Inorder Traversal - Leetcode Solutions

105. Construct Binary Tree from Preorder and Inorder Traversal – Leetcode Solutions

Description:

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.

Examples:

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]

Solution in Python:

To construct a binary tree given the preorder and inorder traversal arrays, we can use a recursive approach. The key idea is to recognize that the first element in the preorder array is the root of the tree, and this root element splits the inorder array into left and right subtrees.

Python
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        # Base case: if either preorder or inorder is empty, return None
        if not preorder or not inorder:
            return None

        # The first element in preorder is the root of the tree
        root_val = preorder[0]
        root = TreeNode(root_val)

        # Find the index of the root value in the inorder array
        root_index = inorder.index(root_val)

        # Elements to the left of root_index in inorder are the left subtree
        # Elements to the right of root_index in inorder are the right subtree

        # Construct left and right subtree using recursion
        # For left subtree, pass the appropriate slices of preorder and inorder
        root.left = self.buildTree(preorder[1:root_index+1], inorder[:root_index])
        
        # For right subtree, pass the appropriate slices of preorder and inorder
        root.right = self.buildTree(preorder[root_index+1:], inorder[root_index+1:])

        # Return the constructed tree
        return root

Explanation:

  1. Base Case:
    • If either the preorder or inorder list is empty, return None. This indicates that there are no more nodes to process.
  2. Root Extraction:
    • The first element of the preorder list is the root of the current subtree. Create a new TreeNode with this value.
  3. Inorder Index:
    • Find the index of the root value in the inorder list. This index splits the inorder list into the left and right subtrees.
  4. Recursion for Subtrees:
    • For the left subtree, recursively call buildTree with the left portion of the preorder list (excluding the first element and up to the length of the left subtree) and the left portion of the inorder list (up to the root index).
    • For the right subtree, recursively call buildTree with the right portion of the preorder list (starting after the elements of the left subtree) and the right portion of the inorder list (starting after the root index).
  5. Return the Root:
    • After constructing the left and right subtrees, attach them to the root node and return the root.

This approach ensures that the binary tree is constructed correctly by utilizing the properties of preorder and inorder traversals. The time complexity is O(n^2) in the worst case due to the index operation, but it can be optimized to O(n) using a hashmap to store the indices of inorder elements.

Solution in Javascript:

JavaScript
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    // Helper function to recursively build the tree
    function helper(preorder, inorder) {
        // Base case: if either array is empty, return null
        if (preorder.length === 0 || inorder.length === 0) {
            return null;
        }
        
        // The first element in preorder is the root of the tree/subtree
        const rootVal = preorder[0];
        const root = new TreeNode(rootVal);
        
        // Find the index of the root value in the inorder array
        const rootIndex = inorder.indexOf(rootVal);
        
        // Elements to the left of rootIndex in inorder are part of the left subtree
        const leftInorder = inorder.slice(0, rootIndex);
        // Elements to the right of rootIndex in inorder are part of the right subtree
        const rightInorder = inorder.slice(rootIndex + 1);
        
        // Elements corresponding to leftInorder in preorder
        const leftPreorder = preorder.slice(1, 1 + leftInorder.length);
        // Elements corresponding to rightInorder in preorder
        const rightPreorder = preorder.slice(1 + leftInorder.length);
        
        // Recursively build the left and right subtrees
        root.left = helper(leftPreorder, leftInorder);
        root.right = helper(rightPreorder, rightInorder);
        
        // Return the constructed tree
        return root;
    }
    
    // Call the helper function with the initial arrays
    return helper(preorder, inorder);
};

Solution in Java:

Java
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // HashMap to store the index of each value in inorder array for quick access
        Map<Integer, Integer> inorderIndexMap = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            inorderIndexMap.put(inorder[i], i);
        }
        // Call the helper function with initial parameters
        return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, inorderIndexMap);
    }
    
    private TreeNode helper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inorderIndexMap) {
        // Base case: if there are no elements to construct the tree
        if (preStart > preEnd || inStart > inEnd) {
            return null;
        }
        
        // The first element of preorder is the root of the current subtree
        int rootVal = preorder[preStart];
        TreeNode root = new TreeNode(rootVal);
        
        // Get the index of the root in the inorder array
        int rootIndex = inorderIndexMap.get(rootVal);
        
        // Calculate the number of elements in the left subtree
        int leftSubtreeSize = rootIndex - inStart;
        
        // Recursively build the left subtree
        root.left = helper(preorder, preStart + 1, preStart + leftSubtreeSize, inorder, inStart, rootIndex - 1, inorderIndexMap);
        
        // Recursively build the right subtree
        root.right = helper(preorder, preStart + leftSubtreeSize + 1, preEnd, inorder, rootIndex + 1, inEnd, inorderIndexMap);
        
        return root;
    }
}

Solution in C#:

C#
using System.Collections.Generic;

public class Solution {
    public TreeNode BuildTree(int[] preorder, int[] inorder) {
        // Create a dictionary to store the index of each value in inorder array for quick access
        Dictionary<int, int> inorderIndexMap = new Dictionary<int, int>();
        for (int i = 0; i < inorder.Length; i++) {
            inorderIndexMap[inorder[i]] = i;
        }
        // Call the helper function with initial parameters
        return BuildTreeHelper(preorder, 0, preorder.Length - 1, inorder, 0, inorder.Length - 1, inorderIndexMap);
    }

    private TreeNode BuildTreeHelper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Dictionary<int, int> inorderIndexMap) {
        // Base case: if there are no elements to construct the tree
        if (preStart > preEnd || inStart > inEnd) {
            return null;
        }

        // The first element of preorder is the root of the current subtree
        int rootVal = preorder[preStart];
        TreeNode root = new TreeNode(rootVal);

        // Get the index of the root in the inorder array
        int rootIndex = inorderIndexMap[rootVal];

        // Calculate the number of elements in the left subtree
        int leftSubtreeSize = rootIndex - inStart;

        // Recursively build the left subtree
        root.left = BuildTreeHelper(preorder, preStart + 1, preStart + leftSubtreeSize, inorder, inStart, rootIndex - 1, inorderIndexMap);

        // Recursively build the right subtree
        root.right = BuildTreeHelper(preorder, preStart + leftSubtreeSize + 1, preEnd, inorder, rootIndex + 1, inEnd, inorderIndexMap);

        return root;
    }
}

Subscribe
Notify of

0 Comments
Inline Feedbacks
View all comments

Popular