每个都有 n k 大小的数组。
a0[0],a0[1],......a0[k-1]
a1[0],a1[1],......a1[k-1]
.
.
.
an-1[0],an-1[1], .... an-1[k-1]
根本没有重复项,所有数组都已排序。
现在,通过从每个数组中随机取任何值来构造一组大小 n 。
例如,一个这样的集可以是{a0[0],a1[3],a2[2],.... an-1[k-1]}
。
我的目标是找出所有可能集合中的最小和最大元素,使得最小值和最大值之间的差异最小。
示例(k = 3,n = 3)
[3 7 11]
[1 12 15]
[4 19 21]
所以在数学上会有27个这样的集合
(3 1 4) (3 12 4) (3 15 4)
(3 1 19) (3 12 19) (3 15 19)
(3 1 21) (3 12 21) (3 15 21)
(7 1 4) (7 12 4) (7 15 4)
(7 1 19) (7 12 19) (7 15 19)
(7 1 21) (7 12 21) (7 15 21)
(11 1 4) (7 12 4) (11 15 4)
(11 1 19) (7 12 19) (11 15 19)
(11 1 21) (7 12 21) (11 15 21)
在计算所有这些集合的最小值和最大值之后,我们可以得出结论:(3 1 4)是min(1)和max(4)之间的差值是全局最小值或最小值的集合。
因此我们将输出3作为全局最小差异,并输出相应的对(3 4)。如果有多个全局最小值,则将它们全部打印出来。请建议具有更好时间和空间复杂度的算法。我们不能采取蛮力的方法。
答案 0 :(得分:1)
迭代所有n * k
个元素。
假设我们当前元素的值为v
。假设v
是结果n元组中的最小值,让我们计算最小差异。
二进制搜索v
在其他n - 1
数组中的位置(因为它们已经排序,我们可以这样做),并注意到为了减少差异,最好选择最小的元素对于所有其他数组,大于或等于v
。这正是二元搜索给我们带来的。
示例:
[3 7 11]
[1 12 15]
[4 19 21]
如果我们在第二个数组上取v = 1
,那么我们将在第一个数组上选择3,在第二个数组上选择4。
复杂性为O(N * K * N * log(N)) = O(N^2 * log(N) * K)
。
答案 1 :(得分:1)
如果我理解正确,您希望找到其元素中最大差异全局最小的集合。 (我将称之为集合的范围)
从k集开始,每个集最初包含第一个数组中的一个元素。对于每个集合,最小值和最大值将等于元素本身。 对于您的示例{3},{7}和{11}。
然后你转到第二个数组。对于每个集合,您必须从该数组中选择一个最小化新范围的元素。理想情况下,您会选择一个不会增加范围的元素(但现在不可能)。如果无法做到这一点,请选择向两个方向展开集合的元素(加号和减号)。对于提供{1-3},{3-12},{1-7},{7-12},{1-11}和{11-12}的示例。从这些 2k 集中,您可以删除重叠的集。例如,与集合{1-3}相比,集合{1-7}将始终具有更大或相等的范围。您无需调查{1-7}集。你最终得到了集合{1-3}和{11-12}。
继续第三个数组,再次选择扩展每个集合范围的元素尽可能小。最终得到{1-4},{11-19}和{4-12}。然后只需选择范围最小的那个。
答案 2 :(得分:1)
该算法的复杂度为O(n * k * logn)
仅选择每行中的第一个元素,并创建最小堆和最大堆。
计算当前差异(= head(maxHeap)-head(minheap))
删除minHeap的头部(以及maxHeap中的相应元素),并将相应数组中的下一个元素(对应于删除的元素)添加到minHeap和maxHeap。
重复此过程,直到其中一个阵列中的所有元素都耗尽。
复杂性:您添加/删除nk元素并且更新最多需要O(n)时间。所以复杂性是O(nklogn)。
注意:这不完全是你的库存堆。 minHeap包含指向maxHeap中相同元素的指针,反之亦然。从minHeap中删除元素时,可以找到maxHeap的链接并将其删除。此外,只要特定元素的位置发生变化,就会对另一个堆中的链接进行适当的更改。
答案 3 :(得分:0)
将结果Set视为一个简单的1xn数组
[3]
[1]
[4]
其中全局差异为3(最小值为4,最小值为1)。
现在考虑Set的扩展定义,称之为MultiSet。 MultiSet是一个数组,其中每个元素包含一组有序的项。
[3 7 11]
[1 12 15]
[4 19 21]
我们可以通过每行的最大“最后”值与每行的最小“第一”值之间的差异来计算全局差异(称为“成本”)。在这种情况下,费用将是21(max(11,15,21)
)和1(min(3,1,4)
)之间的差异,即20。
现在,该过程将迭代MultiSet,直到我们使用以下算法达到最低成本:
为了演示在给定的示例中,通过删除1
的最低值(MultiSet中最低值低于任何其他行最小值)或减少的最低值,可以将原始成本减少到18。从最后一行中删除19
和21
的最高值(MultiSet中的最高值,高于任何其他行的最大值,即15
)。生成的MultiSet将是
[3 7 11]
[1 12 15]
[4]
第二次迭代让我们删除12
和15
以将费用降低到10。
[3 7 11]
[1]
[4]
第三次也是最后一次迭代让我们删除7
和11
以将成本降低到3.在第三次迭代之后,不再能够最小化全局差异,从而达到解决方案。
复杂性?上限由O(n * m * log(n)* k)
组成答案 4 :(得分:0)
代码:
private static ElementData calcMin(int[] n1Arr, int[] n2Arr, int[] n3Arr) {
ElementData data = new ElementData();// added just to know which two elements algo has picked
int[] mixArr = { n1Arr[0], n2Arr[0], n3Arr[0] };
Arrays.sort(mixArr);
int minValue = mixArr[2] - mixArr[0];
data.setMinValue(minValue);
data.setHighValue(mixArr[2]);
data.setLowValue(mixArr[0]);
int tempValue = 0;
for (int n1 : n1Arr) {
for (int n2 : n2Arr) {
for (int n3 : n3Arr) {
int[] mixArr1 = { n1, n2, n3 };
Arrays.sort(mixArr1);
tempValue = mixArr1[2] - mixArr1[0];
if (minValue > tempValue) {
minValue = tempValue;
data = new ElementData();
data.setMinValue(minValue);
data.setHighValue(mixArr1[2]);
data.setLowValue(mixArr1[0]);
}
}
}
}
return data;
}