Advertisement

Number of Ways to Reorder Array to Get Same BST - LeetCode 1569 Solution

Number of Ways to Reorder Array to Get Same BST - Complete Solution Guide

Number of Ways to Reorder Array to Get Same BST is LeetCode problem 1569, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Given an array nums that represents a permutation of integers from 1 to n . We are going to construct a binary search tree (BST) by inserting the elements of nums in order into an initially empty BST. Find the number of different ways to reorder nums so that the constructed BST is identical to that formed from the original array nums . For example, given nums = [2,1,3] , we will have 2 as the root, 1 as a left child, and 3 as a right child. The array [2,3,1] also yields the same BST but [3,2,1]

Detailed Explanation

The problem asks us to find the number of ways to reorder an array `nums` such that the binary search tree (BST) constructed by inserting the elements of the reordered array into an initially empty BST is identical to the BST constructed from the original array `nums`. The array `nums` contains a permutation of integers from 1 to n. We need to return the number of such reorderings modulo 10^9 + 7.

Solution Approach

The solution uses a recursive approach combined with combinatorics to calculate the number of valid reorderings. It first builds a helper function `dfs` that takes an array as input. This function recursively calculates the number of ways to reorder the given array such that it results in the same BST. Inside the `dfs` function, it divides the array into left and right subtrees based on the root node (the first element). Then, it uses combinations to calculate the number of ways to interleave the left and right subtrees. Finally, it recursively calls `dfs` on the left and right subtrees and multiplies the results together, modulo 10^9 + 7. A combination table is precomputed using dynamic programming to calculate combination values efficiently. The initial call to `dfs` is made with the original `nums` array and we subtract 1 from the final result to exclude the original array itself.

Step-by-Step Algorithm

  1. Step 1: Precompute the combinations table C[i][j] using dynamic programming. This table will store the values of 'i choose j' modulo 10^9 + 7.
  2. Step 2: Define a recursive function `dfs(arr)` that takes an array `arr` as input.
  3. Step 3: Base Case: If the length of `arr` is less than or equal to 2, return 1 (as there is only one way to reorder).
  4. Step 4: Divide the array `arr` into two subarrays: `left_nodes` containing elements smaller than the root (arr[0]) and `right_nodes` containing elements larger than the root.
  5. Step 5: Calculate the number of ways to interleave the left and right subtrees using combinations: `C[len(arr) - 1][len(left_nodes)]`.
  6. Step 6: Recursively calculate the number of ways to reorder the left and right subtrees using `dfs(left_nodes)` and `dfs(right_nodes)`.
  7. Step 7: Multiply the number of ways to interleave, the number of ways to reorder the left subtree, and the number of ways to reorder the right subtree, all modulo 10^9 + 7. This gives the number of ways to reorder `arr`.
  8. Step 8: Return the result from the recursive function.
  9. Step 9: In the main function, call the `dfs` function with the input array `nums`.
  10. Step 10: Subtract 1 from the result (to exclude the original array) and take the modulo 10^9 + 7. This handles the edge case where we don't want to count the original array.

Key Insights

  • Insight 1: The root of the BST will always be the first element of the array. The remaining elements can be divided into two groups: those smaller than the root (left subtree) and those larger than the root (right subtree).
  • Insight 2: The order of elements within the left and right subtrees doesn't affect the BST structure, but their relative order with respect to each other (left elements before right elements) does.
  • Insight 3: We can use combinations to count the number of ways to interleave the left and right subtrees. The formula for combinations (nCr) is crucial for calculating the possible arrangements.
  • Insight 4: Recursion and Divide and Conquer are suitable techniques to solve this problem because the subtrees can be solved independently and the results can be combined.

Complexity Analysis

Time Complexity: O(n^2)

Space Complexity: O(n^2)

Topics

This problem involves: Array, Math, Divide and Conquer, Dynamic Programming, Tree, Union Find, Binary Search Tree, Memoization, Combinatorics, Binary Tree.

Companies

Asked at: DE Shaw.