def numTrees(self, n):
"""
Solution Method
算法:动规
思路:
非常巧妙!
首先一定要找到下手点,BST是有有序数组的二叉搜索构建而来的,即某个节点的左节点都比他小,右节点都比他大,利用
这个特点去解题。还原本质,找到状态转移方程
首先看一个数组
[1,2,3,4,5,6]
如果以3作为root,那么就可以分割为[1,2,] 3 [4,5,6],这样的话以3为root的BST的个数,就是左侧[1,2]的BST的个数
乘上右侧[4,5,6]的BST的个数,即这个长度为6的数组dp[6]= SUM(F(i)),i从1到6,F(i) = m * n,m是左侧BST的个数,n是
右侧BST的个数,即F(i) = F(i-1) * F(n-i)
但是要注意到!构建BST的这个过程,事实上是和具体的值无关的,即[3,4,5],[101,102,103]这样的数,所能构建出的BST
的个数是一样的!即只取决于有序列表的长度,而不取决于具体的列表内的内容。
所以可以将F(i) = F(i-1) * F(n-i) 转化为dp[i-1]*dp[n-i]
如此一来dp[n] = sum(dp[i-1]*dp[n-i]),i from 1...n
边界条件的话,dp[0] = 1,空树,1个
dp[1] = 1,就一个数字,就一个树
"""
dp = [0] * (n + 1)
dp[0], dp[1] = 1, 1
for i in range(2, n + 1):
for j in range(1, n + 1):
dp[i] += dp[j - 1] * dp[i - j]
return dp[-1]