zoukankan      html  css  js  c++  java
  • 96题--不同的二叉搜索树(java、中等难度)

    题目描述:给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

    示例如下:

    分析:本题可用动态规划的方法求解。

      设 dp[n] 表示以 1 ... n 为节点组成的二叉搜索树的种类,我们做如下讨论:

    1)当头结点的值为1时,左子树为空,即左子树可能出现的二叉搜索树的结构数为1。右子树上有(n - 1)个结点,此时右子树(n-1)个结点可能组成的二叉搜索树的个数为 dp[n-1]。

    那么总的可能出现的二叉搜索树的结构数 dp[n] = 左子树可能结构数 * 右子树可能结构数 = 1 * dp[n-1]

    2)当头结点的值为 i (1 < i < n) 时,左子树的结点为:1 —> i-1  ,这 (i-1) 个结点可能组成的二叉搜索树的个数为 dp[i-1];右子树的结点为:i+1 —> n  ,这 (n-i) 个结点可能组成的二叉搜索树的个数为 dp[n-i].

    那么,左右子树以及头结点 i 组成的二叉搜索树可能的结构种类为:dp[i] = dp[i-1] * dp[n-i]

    3)当头结点的值为n时,右子树为空,左子树上有(n - 1)个结点,此时左子树(n-1)个结点可能组成的二叉搜索树的个数为 dp[n-1];

    那么总的可能出现的二叉搜索树的结构数 dp[n] = dp[n-1] * 1

      另外,n = 0 时 dp[0] = 1,因为空树也算一种二叉搜索树;那么n = 1时的情况可以看做是其左子树可能结构数乘以右子树可能结构数,左右字数都是空树,所以1乘1还是1,dp[1]=1。

      终上所述:dp[n] = dp[0] * dp[n-1] + dp[1] * dp[n-2] + ...... + dp[i-1]*dp[n-i] + ...... + dp[n-2] * dp[1] + dp[n-1] * dp[0] 。这实际上是一个卡特兰数问题。

       

       那么,根据以上递推公式,我们可以从0开始,求得每一个 dp[i],这样就可以递推得到dp[n],这种方法的时间复杂度是 O(n^2) ,因为代码内部有2层循环。

      代码如下(java语言):

     1     public int numTrees(int n)
     2     {
     3         //定义一个长度为 n+1 的数组,用于存储 dp[1] - dp[n]
     4         int[] dp = new int[n+1];
     5         dp[0] = 1;
     6         dp[1] = 1;
     7 
     8         //通过2层循环,i=2,...,n 找到每一个dp[i]
     9         for (int i = 2; i <= n ; i++)
    10         {
    11             for (int j = 0; j <= i-1 ; j++)
    12             {
    13                 dp[i] += dp[j] * dp[i-j-1];
    14             }
    15         }
    16 
    17         return dp[n];
    18     }
    19         



  • 相关阅读:
    学习笔记2
    带有循环的存储过程
    经典SQL语句大全
    关于职业的一些看法
    把dataTable表批量的写入数据库
    抽奖接口,每天只能抽奖3次,而且必须先登录才能抽奖的小程序
    调用获取学生信息的接口,保存到excel里面的小程序
    内置函数补充
    好用的模块
    网络编程
  • 原文地址:https://www.cnblogs.com/KongJetLin/p/13054624.html
Copyright © 2011-2022 走看看