Stage 4: Advanced Techniques·Combinatorics & Counting
Hard#15699 min readMathCombinatoricsRecursionLeetCode

Ways to Reorder Array to Get Same BST

Recursive split with C(n,k)

Recursive decomposition + nCr. Beautiful problem for your background.

Published Apr 16, 2026

Problem

Given an array nums of distinct integers, a BST is built by inserting elements left-to-right (the first element is the root). Return the number of different permutations of nums that would produce the same BST, modulo 10^9 + 7. The answer excludes the original ordering, so subtract 1.

Input
nums = [2, 1, 3]
Output
1
Explanation
Root is 2. Left subtree {1}, right {3}. The only other valid ordering is [2, 3, 1]. So 2 total orderings - 1 = 1.
Input
nums = [3, 4, 5, 1, 2]
Output
5
Explanation
Root is 3. Left {1, 2}, right {4, 5}. 6 valid orderings. 6 - 1 = 5.
Input
nums = [1, 2, 3]
Output
0
Explanation
Root is 1, everything goes right in a chain. Only one valid insertion order exists.

Intuition

The first element is always the root. Elements smaller go left, larger go right. Within each subtree, the relative order must produce the same sub-BST — recursively.

Given left subtree size L and right subtree size R, the number of valid interleavings of two independent sequences is C(L + R, L) — choose which positions in the combined sequence belong to the left subtree.

So: ways(node) = C(L + R, L) * ways(left) * ways(right).

The answer is ways(root) - 1 (exclude the original ordering).

Precompute Pascal's triangle for C(n, k) modular, then recurse.

Interactive concept

Same BST Reorder Counting

The root is fixed; reorder left and right subtree values while preserving each subtree shape.

Root partitions values

Every value smaller than root must end up in the left subtree; larger values go right.

3
1
2
5
4

Approach

Recursive Split with C(n,k)

TimeO(n²)
SpaceO(n²)
Recommended

Precompute C[n][k] via Pascal's triangle mod 10^9 + 7. Recurse: for each subtree, partition into left (smaller than root) and right (larger), multiply C(|left|+|right|, |left|) by recursive results.

impl Solution {
    pub fn num_of_ways(nums: Vec<i32>) -> i32 {
        const MOD: i64 = 1_000_000_007;
        let n = nums.len();

        // Pascal's triangle.
        let mut c = vec![vec![0i64; n + 1]; n + 1];
        for i in 0..=n {
            c[i][0] = 1;
            for j in 1..=i {
                c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
            }
        }

        fn count(arr: &[i32], c: &[Vec<i64>]) -> i64 {
            const MOD: i64 = 1_000_000_007;
            if arr.len() <= 1 {
                return 1;
            }
            let root= arr[0];
            let left: Vec<i32> = arr[1..].iter().copied().filter(|&x| x < root).collect();
            let right: Vec<i32> = arr[1..].iter().copied().filter(|&x| x > root).collect();
            let ways = c[left.len() + right.len()][left.len()]
                % MOD
                * count(&left, c)
                % MOD
                * count(&right, c)
                % MOD;
            ways
        }

        ((count(&nums, &c) - 1 + MOD) % MOD) as i32
    }
}
Rust · runnable

Trace

nums = [3, 4, 5, 1, 2]:

Counting#1569

Ways to Reorder Array to Get Same BST walkthrough

nums = [3,4,5,1,2]

Step 1 of 30%
root
3
left
[1,2]
right
[4,5]

Root 3 sends [1,2] left and [4,5] right.

Split by the root

Decision

Solve both subarrays recursively.

Update

Left ways = 1, right ways = 1.

Why it works

BST insertion shape is determined by relative comparisons to each root.

Invariant

The root stays first; values less than root and greater than root must preserve their internal BST shapes.

Finish

Total reorderings = 6, answer = 5 after excluding the original order.

Subtract one only at the top-level answer.Precompute nCr modulo MOD for interleavings.

Total = 6. Answer = 6 - 1 = 5.

Edge cases

  • Sorted input — all elements go right in a chain. Only 1 valid ordering. Answer = 0.
  • Reverse sorted — all elements go left. Same: answer = 0.
  • Two elements — root + one child. C(1, 0) = 1 or C(1, 1) = 1. Answer = 0.
  • Balanced split — maximizes the combinatorial factor; gives the largest answer.

Takeaway

BST structure is determined by relative order, not absolute values. The interleaving count C(L + R, L) captures exactly how many ways two independent sequences can be shuffled while preserving their internal orders. This is the same "shuffle" counting that appears in merge-sort analysis and multi-threaded scheduling.

More in Combinatorics & Counting