給定一列不重復的數,依次插入一棵空樹構成二叉搜索樹,問若打亂這一列數的順序,一共有多少種不同的打亂方式,可以得到一樣的BST,遞歸分治思想
假設當前數列長l,那么第一個數字決定了root的位置,無法移動,之后的數字比root大的數和比root小的數的數量是一定的,假設有m個數比root大,n個數比root小(m+n+1=l)。那么打亂順序還可以構成一樣的BST的數量就是組合數C(m, m+n)。而左子樹和右子樹又將進行同樣的計算。注意最終結果要-1(減去原本的那種排列方式)
1 #1569
2 #Runtime: 173 ms (Beats 71.74%)
3 #Memory: 21.8 MB (Beats 51.9%)
4
5 class Solution:
6 def numOfWays(self, nums: List[int]) -> int:
7 MOD = 10 ** 9 + 7
8
9 def cal(seq):
10 if not seq:
11 return 1
12 root = seq[0]
13 l_tree = [num for num in seq if num < root]
14 r_tree = [num for num in seq if num > root]
15 return math.comb(len(l_tree) + len(r_tree), len(l_tree)) * cal(l_tree) * cal(r_tree) % MOD
16 return (cal(nums) - 1) % MOD