具有给定右臂伸展的二叉搜索树的数量

时间:2014-02-11 07:27:26

标签: algorithm data-structures dynamic-programming combinatorics

对于给定的不同(唯一)整数数组,我想知道长度为k的最右臂的所有排列中的BST数。 (如果k = 3,则root-> right-> right是叶节点)

(根据我目前的要求,我买不起费用大于N ^ 3的算法)

从不同的排列生成的两个相同的BST被认为是不同的。

到目前为止,我的方法是:

假设一个功能:

F(arr) = {a1, a2, a3...}

其中a1是k = 1的数组计数,a2是k2等数组的计数。

F(arr [1:n])=对于i在范围1到n(1 + df * F(每个元素大于arr [i]的子区域)) 其中df是动态因子(n-1)C(小于arr [i]的元素数)

我正在尝试创建一个解决问题的dp

  • 对数组进行排序
  • 从最大号码开始到较小号码
  • dp [i] [i] = 1
  • for(j在范围i-1到1中)dp [j] [i] = dp [j] [i-1]的某些函数,但我无法表达

对于ex:for arr {4,3,2,1},我期待以下dp

          arr[i]  4   3   2   1
                +---+---+---+---+
         k = 1  | 1 | 1 | 2 | 6 |
                +---+---+---+---+
         k = 2  | - | 1 | 3 |11 |
                +---+---+---+---+
         k = 3  | - | - | 1 | 6 |
                +---+---+---+---+
         k = 4  | - | - | - | 1 |
                +---+---+---+---+
verification(n!) 1    2   6   24

欢迎任何提示,建议,指示或重定向到我能满足好奇心的好来源。

谢谢。

编辑:似乎我可能需要3D dp数组。我正在努力。 编辑:更正了dp的第3列

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题。

  1. 您无需对数组进行排序。由于数组中的所有数字都是唯一的,因此您可以假设每个可能的子树都是唯一的。

  2. 因此,您只需要计算您可以构建具有N-k个唯一元素的唯一树,其中N是数组的长度,k是最右臂的长度。换句话说,如果将右子树修复为固定结构(root(node1(node2 ... nodeK)),它将是左子树的排列数。)

  3. 这是一种计算大小为N的二叉树数量的方法:

    public int numTrees(int n) {
    
        int[] ut = new int[Math.max(n + 1, 3)];
    
        ut[1] = 1;
        ut[2] = 2;
    
        for (int i = 3; i <= n; i++) {
            int u = 0;
            for (int j = 0; j < i; j++) {
                u += Math.max(1, ut[j]) * Math.max(1, ut[i - j - 1]);
            }
            ut[i] = u;
        }
    
        return ut[n];
    }
    

    它具有O(n ^ 2)时间复杂度和O(n)空间复杂度。

答案 1 :(得分:0)

好新的是你不想要排列而只需要他们的数字,有一个公式。这些被称为(无符号)Stirling numbers of the first kind。原因是二叉搜索树右臂上出现的数字是从左到右的最小值,即i,使得出现在{{{}之前的数字1}}大于i。以下是记录带下划线的示例

i

这给了树

 6 8 3 5 4 2 7 1 9
 _   _     _   _

根据各种特征(循环次数......),知道这些数字可以计算排列。众所周知,最大值或最小值属于这些特征。你可以找到关于整数序列在线百科全书的Entry A008275的更多信息。

现在回答计算它们的问题。让 6 3 8 2 5 7 9 1 4 S(n,k)数字的排列数,其中n从左到右为最小值。您可以使用重复:

    所有k
  • S(n, 0) = 0 所有nS(n+1, k) = n*S(n, k) + S(n, k-1)
  • n>0