96. 不同的二叉搜索树(困难)
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 2 3 4 5
| 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
|
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees
思路1:
假设n个节点存在二叉排序树的个数是G(n),令f(i)为以i为根的二叉搜索树的个数,则
G(n) = f(1) + f(2) + f(3) + f(4) + … + f(n)
当i为根节点时,其左子树节点个数为i-1个,右子树节点为n-i,则
f(i) = G(i-1)*G(n-i)
综合两个公式可以得到 卡特兰数 公式
G(n) = G(0)G(n-1)+G(1)(n-2)+…+G(n-1)*G(0)
作者:guanpengchn
链接:https://leetcode-cn.com/problems/unique-binary-search-trees/solution/hua-jie-suan-fa-96-bu-tong-de-er-cha-sou-suo-shu-b/
思路2:
动态规划
这尼玛,谁能想出来,简直了
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public int numTrees(int n) { int[] dp = new int[n+1]; dp[0]=1; dp[1]=1; for(int i=2;i<=n;i++){ for(int j=1;j<=i;j++){ dp[i] += dp[j-1]*dp[i-j]; } } return dp[n]; } }
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class Solution { public int numTrees(int n) { return count(1,n); } int count(int low,int high){ if(low>high){ return 1; } int res =0; for(int i=low;i<=high;i++){ int left = count(low,i-1); int right = count(i+1,high); res += left*right; } return res; } }
class Solution { int[][] memo; public int numTrees(int n) { memo = new int[n+1][n+1]; return count(1,n); } int count(int low,int high){ if(low>high){ return 1; } if(memo[low][high]!=0){ return memo[low][high]; } int res =0; for(int i=low;i<=high;i++){ int left = count(low,i-1); int right = count(i+1,high); res += left*right; } memo[low][high] = res; return res; } }
|