LintCode 不同的二叉查找树

不同的二叉查找树

给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?

给出n = 3,有5种不同形态的二叉查找树:

1          3     3      2      1
 \        /     /      / \      \   3      2     1      1   3      2
 /      /       \                 \ 2     1          2                 3

Solution:
对于该问题我们可以使用动态规划来求解。。对于动态规划问题我们需要确定问题的状态和状态转换方程。

首先我们来确定问题的状态:给定 i(1in) , 由 1...i 组成的不同的二叉查找树有 f(i) 种。
因此,
i=1 时 , 只有一个节点, f(1)=1 .
i=2 时,存在两个节点1, 2。当以2作为根节点是只有1中,以1作为根节点时也只有1种,因此总共有2种。
i=3 时,存在三个节点1,2,3。我们来进行详细的叙述。
以3根节点时。其它的节点1,2只能在左子树。及

      3
     /
  {1, 2}, 此时就转换成了{1,2}有多少种二叉树。因此,3为根节点时有2中不同的二叉树   

以2为根节点时,节点3只能在右子树,节点1只能在左子树。及

          2
         / \
      {1}  {3}, 由于左子树只有一个节点因此只有1种,同样右子树也只有1中。因此2为根节点有1x1=1种。

以1为根节点时,节点{2,3}只能在右子树。及

   1
    \
    {2,3}, 此时就变成{2,3}有多少种二叉树{2,3}=f(2)。因此1为根节点有2种。

因此有f(3) = 2 + 1 + 2 = 5种。

分析到这里状态转换方程应该很容易写出来了吧?!
对于 i , 以 k(1ki) 作为根节点, 左子树的节点为 1,...,k1 共有 k1 个节点,右子树的节点为 k+1,...,i 共有 ik 个节点。因此,状态装换方程为
f(i)=ik=1f(k1)×f(ik)
注意:边界条件f(0)=1
上述等式还可以继续进行优化,这里不再详细叙述。详见代码.

public class Solution {
    /** * @paramn n: An integer * @return: An integer */
    public int numTrees(int n) {
        // write your code here
        int [] res = new int[n+1];
        res[0] = 1;

        for (int i = 1; i <= n; ++i) {
            for (int j = i-1; j >= i/2; --j) {
                if (i%2==1 && j == i/2)
                    res[i] += res[j] * res[i-j-1];
                else
                    res[i] += res[j] * res[i-j-1]*2;
            }
        }
        return res[n];
    }
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/shinanhualiu/article/details/50225093
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞