class Solution:
    def numOfWays(self, nums: List[int]) -> int:
        """
        main idea: with fixed root node, we can get list of left subtree and right subtree; we just need to keep both subtree's relative position in order 
                    - using Pasca; triangle 
        ==> note, given one sequence, we can get a tree but given one tree  we can generate multiple sequences.
        """
        M = 10**9+7
        n = len(nums)
        # build pascal triangle
        d = {}
        for i in range(n+1):
            d[i] = [1] * (i+1)
            for j in range(1,i):
                d[i][j] = (d[i-1][j-1]+d[i-1][j])%M
        def dfs(A):
            n = len(A)
            if n < 2:return 1
            # seperate left subtree and right subtree 
            left,right = [],[]
            for i in range(1,n):
                if A[i] < A[0]:
                    left.append(A[i])
                else:
                    right.append(A[i])
            # dfs left, right seperately 
            left_res = dfs(left)%M
            right_res = dfs(right)%M
            return (d[n-1][len(left)]*left_res) % M *right_res % M
        return dfs(nums)%M -1

Easy to understand Solution

class Solution:
    def numOfWays(self, nums: List[int]) -> int:
        """
        main idea: using interleave concept,  res = sequence of  left subtree L * sequence of right subtree * C(L+R,L) -1
                - as only as we decide the root node, left subtree and right subtree will be determined. All the rest we need to do is to count the left subtree sequence and right subtree sequence 
        """
        M = 10**9+7
        def ways_to_interleave(seq1:List[int],seq2:List[int]):
            total = len(seq1) + len(seq2)
            return math.comb(total,len(seq1)) 
        
        def dfs(subseq:List[int]):
            if not subseq:
                return 1
            root_val = subseq[0]
            left = [x for x in subseq if x < root_val]
            right = [x for x in subseq if x > root_val]
            ways_to_arrange_left = dfs(left)
            ways_to_arrange_right = dfs(right)
            return ways_to_arrange_left * ways_to_arrange_right * ways_to_interleave(left,right)
        return (dfs(nums)-1) % M