Question
Given n, how many structurally unique BST’s (binary search trees) that store values 1…n?
给出n,可以组成多少个不重复的BST(二叉查找树),其中每个结点的值为1…n
Example
Given n = 3, there are a total of 5 unique BST’s.
Solution
动态规划解。为了保证计算得到的BST都是不重复的,我们分别以每个结点(1…n)作为根节点。根据二叉树的特点,大于根节点的结点在其右子树,小于根节点的结点在其左子树。所以我们定义dp[i]:i个结点组成的不重复的BST个数。要计算dp[i],我们只需分别计算以1…i作为根结点时的BST个数,而假设计算以j(j <= i)为根节点的BST个数我们只需要计算其左子树和右子树的BST个数,并将它们相乘即可。所以递推式:dp[i] += dp[j - 1] * dp[i - j] (j <= i),它代表以j为根节点,dp[j - 1]代表其左子树的BST个数(即由j-1个结点能够组成几种BST),dp[i - j]代表其右子树的BST个数。
# 递归版,不能AC,这里只是显示逻辑更易于理解 class Solution(object): def numTrees(self, n): """ :type n: int :rtype: int """ return self.solve(n) def solve(self, n): if n <= 1: return 1 ways = 0 # 分别计算以1...n作为根节点的BST个数 for i in range(1, n + 1): # 每个i作为根结点时的BST个数 = 左子树可以组成的BST个数 * 右子树可以组成的BST个数 # 其实就是i - 1和n - i个结点能够组成的BST的个数 ways += self.solve(i - 1) * self.solve(n - i) return ways
class Solution(object): def numTrees(self, n): """ :type n: int :rtype: int """ if n == 0: return 0 dp = [0] * (n + 1) dp[0] = dp[1] = 1 for index_n in range(2, n + 1): # 分别计算以j为根(j代表1...index_n)的二叉树的个数,并计算总和 for j in range(1, index_n + 1): dp[index_n] += dp[j - 1] * dp[index_n - j] return dp[-1]