对于给定的不同(唯一)整数数组,我想知道长度为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
对于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列
答案 0 :(得分:0)
如果我理解你的问题。
您无需对数组进行排序。由于数组中的所有数字都是唯一的,因此您可以假设每个可能的子树都是唯一的。
因此,您只需要计算您可以构建具有N-k个唯一元素的唯一树,其中N是数组的长度,k是最右臂的长度。换句话说,如果将右子树修复为固定结构(root(node1(node2 ... nodeK)),它将是左子树的排列数。)
这是一种计算大小为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
所有n
和S(n+1, k) = n*S(n, k) + S(n, k-1)
n>0