Leetcode 96.不同的二叉搜索树
1 题目描述(Leetcode题目链接)
给定一个整数 n,求以 1 ⋯ n 1 \cdots n 1⋯n 为节点组成的二叉搜索树有多少种?
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
2 题解
动态规划问题,并且本题为卡特兰数,卡特兰数满足的形式如下:
h
(
n
)
=
h
(
0
)
∗
h
(
n
−
1
)
+
h
(
1
)
∗
h
(
n
−
2
)
+
⋯
+
h
(
n
−
1
)
∗
h
(
0
)
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + \cdots + h(n-1)*h(0)
h(n)=h(0)∗h(n−1)+h(1)∗h(n−2)+⋯+h(n−1)∗h(0)
其中
n
≥
2
n \ge 2
n≥2。
回过头来看本题,我们定义
D
P
[
i
]
DP[i]
DP[i]为
i
i
i个节点能组成的二叉搜索树的数量,再来定义一个辅助规则
f
(
j
,
i
)
f(j,i)
f(j,i)表示当有
i
i
i个节点时以
j
j
j为根节点的二叉搜索树的数量。那么显然:
D
P
[
i
]
=
∑
j
=
1
i
f
(
j
,
i
)
DP[i] = \sum_{j = 1}^if(j, i)
DP[i]=j=1∑if(j,i)
由于没有节点和只有一个节点时,二叉搜索树的数量都为1,所以
D
P
[
0
]
=
D
P
[
1
]
=
1
DP[0]=DP[1]=1
DP[0]=DP[1]=1,当
i
≥
2
i\ge 2
i≥2时有状态转移方程:
D
P
[
i
]
=
∑
j
=
1
i
D
P
[
j
−
1
]
∗
D
P
[
i
−
j
]
DP[i] = \sum_{j= 1}^iDP[j - 1]*DP[i - j]
DP[i]=j=1∑iDP[j−1]∗DP[i−j]
class Solution:
def numTrees(self, n: int) -> int:
DP = [0]*(n+1)
DP[1] = DP[0] = 1
for i in range(2, n+1):
for j in range(1, i + 1):
DP[i] += DP[j-1]*DP[i-j]
return DP[-1]