unique-binary-search-trees
题目:
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1 3 3 2 1 / / / 3 2 1 1 3 2 / / 2 1 2 3
解析:题目的意思就是用n个数可以组成多少种结构不一样的二叉查找树。
这里注意二叉查找树的特性,左子树小于根节点,右子树大于根节点。最开始的根节点有n种可能性,对于每一种可能性i(即根节点为i时),
所有结构情况就是根节点的左子树的结构总数*右子树的结构总数。且根节点为i时,它左子树所有元素就是1,...,i-1,总共i-1个数构成的所有情况,
右子树就是i+1,...,n总共n-i个元素构成的所有情况。因为只统计所有情况,所以计算右子树的情况时,i+1,...,n的排列情况总数也就等于1,...,n-i的情况总数
public class Solution { public int numTrees(int n) { if(n<=1) return 1; int sum=0; for(int i=1;i<=n;i++){ sum+=numTrees(i-1)*numTrees(n-i); } return sum; } }
上面采用递归的方式。还可以使用非递归方式,也就是动态规划。
dp[n]表示n个数时的总可能性,这n个数依次可以作为根节点,
假设i作为根节点,此时的可能性是dp[i-1]*dp[n-i],所以dp[n]=dp[0]*dp[n-1]+dp[1]*dp[n-2]+...+dp[n-1]*dp[0],
这里dp[0]设为1,用于补全这个递推式。根据递推公式,我们要依次求出dp[2],dp[3],...dp[n],每一次求的是时候,都会用到上面公式。
class Solution { public int numTrees(int n) { //动态规划的题,设置一个数组存放当前数的总路径数 int[] dp=new int[n+1];///从1开始,0设为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]; } }