unique-binary-search-trees

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];
    }
}
复制代码

 

posted on 2018-01-08 15:42  夜的第八章  阅读(228)  评论(0编辑  收藏  举报

导航