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
.
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]
yields a different BST.Return the number of ways to reorder nums
such that the BST formed is identical to the original BST formed from nums
.
Since the answer may be very large, return it modulo 109 + 7
.
Example 1:
Input: nums = [2,1,3] Output: 1 Explanation: We can reorder nums to be [2,3,1] which will yield the same BST. There are no other ways to reorder nums which will yield the same BST.
Example 2:
Input: nums = [3,4,5,1,2] Output: 5 Explanation: The following 5 arrays will yield the same BST: [3,1,2,4,5] [3,1,4,2,5] [3,1,4,5,2] [3,4,1,2,5] [3,4,1,5,2]
Example 3:
Input: nums = [1,2,3] Output: 0 Explanation: There are no other orderings of nums that will yield the same BST.
Constraints:
1 <= nums.length <= 1000
1 <= nums[i] <= nums.length
nums
are distinct.Given an array nums
representing a permutation of integers from 1 to n, construct a Binary Search Tree (BST) by inserting elements of nums
in order. The task is to find the number of different ways to reorder nums
such that the constructed BST remains identical to the one formed from the original array. The answer might be large, so it should be returned modulo 109 + 7.
This problem can be efficiently solved using a recursive approach combined with combinatorial calculations. The core idea is to leverage the properties of BSTs:
The recursive function dfs(nums)
calculates the number of ways to reorder the input array nums
such that the resulting BST is identical.
nums
has fewer than 2 elements, there's only 1 way (itself).nums
into left
(elements < root) and right
(elements > root).left
and right
subtrees: a = dfs(left)
and b = dfs(right)
.a * b
).C(m+n, m)
, where m
is the size of left
and n
is the size of right
. This coefficient represents the number of ways to choose m
positions out of m+n
total positions.The binomial coefficient C(m+n, m)
is pre-calculated using Pascal's triangle to improve efficiency. We use dynamic programming to compute these coefficients, avoiding redundant computations.
Finally, the result is dfs(nums) - 1
(because the original ordering is already counted), taken modulo 109 + 7.
dfs
function and the pre-computation of binomial coefficients. The recursion explores all possible combinations.class Solution:
def numOfWays(self, nums: List[int]) -> int:
n = len(nums)
mod = 10**9 + 7
c = [[0] * n for _ in range(n)]
c[0][0] = 1
for i in range(1, n):
c[i][0] = 1
for j in range(1, i + 1):
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod
def dfs(nums):
if len(nums) < 2:
return 1
left = [x for x in nums if x < nums[0]]
right = [x for x in nums if x > nums[0]]
m, n = len(left), len(right)
a, b = dfs(left), dfs(right)
return (((c[m + n][m] * a) % mod) * b) % mod
return (dfs(nums) - 1 + mod) % mod
The code in other languages (Java, C++, Go, TypeScript) follows a very similar structure, with the main differences lying in syntax and data structure handling. The core logic of recursion and binomial coefficient calculation remains consistent across all implementations.