给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 / / / 3 2 1 1 3 2 / / 2 1 2 3
dp解题的代码太简洁了;
dp[n]:表示长度为n的序列能组成的不同二叉树个数,且dp[0] = dp[1] = 1;
f(i, n) 表示以i为根节点,由长度为n的序列能组合成的不同二叉树的个数
可以知道dp[n] = f(1, n) + f(2, n) + f(3, n) +... + f(n, n);
现在的问题就转换为如何求f(i, n);
用[1,2,3,4,5,6,7]来解释, 以f(3, 7)为例:
对于一个序列,如果根节点确定了,能构成的不同的二叉树就由其不同的左子树和右子树的个数确定
对于左子树就是求dp([2]; 对于右子树,虽然是4,5,6,7的排列,但是其能组成的二叉树和1,2,3,4的个数是相同的,我们只管能组成的二叉树的个数,而不去管具体的二叉树是怎么样的,所以右子树的个数是dp[n-3];
由此可得f(i,, n) = dp[i-1]*dp[n-i];
所以能得到新的关系式:dp[n] = dp[0]*dp[n-1] + dp[1]*dp[n-2] + ... + dp[n]*dp[0]
1 class Solution { 2 public: 3 int numTrees(int n) { 4 vector<int> dp(n+1); 5 dp[0]=1; dp[1]=1; 6 for(int i=2; i<=n; i++) 7 for(int j=1; j<=i; j++) 8 dp[i] += dp[j-1]*dp[i-j]; 9 return dp[n]; 10 } 11 };