说我有一大套数组(可以达到数百万个大小),并且我想确定(最好是精确的,尽管大约是可以的)该集合中与输入的交点最大的数组是什么?将是最有效的方法吗?我将列出一些解决方案,这些解决方案将其归结为另一个问题,但这些问题却在我的脑海中浮出水面,但我不确定它们是否一定是最好的。
这组数组可以存储在任何数据结构中,并且可以以任何方式对数组进行排序和存储。这个想法是在这里优化查询时间。
示例:说我的一组数组是(为方便起见,以基数排序,可以以任何选择的方式排序):
[('a', 'b'), ('a', 'e', 'f'), ('b', 'f', 'g'), ('b', 'j', 'z'), ('d', 'l', 'f'), ('x', 'y', 'z')]
我的输入数组是:
('a', 'f')
然后各个交叉点是:
[('a'), ('a', 'f'), ('f'), (), ('f'), ()]
因此,输出将是('a', 'f')
,具有最大的2交集。作为奖励,最好拥有其中最大的K
,因此在这里,如果K = 3 ,输出将是(以任何顺序):
[('a', 'f'), ('f'), ('a')]
我想到的一些可能的解决方案:
('a', 'f')
可以表示为10000100000000000000000000
谢谢您的正确回答或指导!
答案 0 :(得分:2)
由于缺乏声誉,我无法通过评论事先提出一些问题:
没有散列集,我将按长度对数组进行排序,并从最长的数组开始,以通过找到仅大于或等于较短的数组大小的交集大小来最终跳过较短的数组。
如果您还对数组本身进行排序,则可以利用Hammington距离,但是不必同时对所有数组进行排序和转换,而只需从它们的一部分开始。如果您不使用Hammington,请记住,如果将输入与输入为大小+ 1的数组进行比较,则只需要进行比较,直到达到第一个比较时输入的最后一个元素小于当前数组即可元素。
a f
a c k z // //由于k> f,我们不需要比较f和z
我认为这种方式归结为O(n lg n)的复杂性,因为按大小对数组进行排序将是O(n lg n),计算大小n * O(1)并进行内部基数运算排序O(n)。比较本身就是O(n lg n)(对此不太确定),所以总数将是O(n lg n)* 2 + 2 * O(n)=> O(n lg n)。>
一个简单的主意:您可以使用Radix对所有数组进行排序并将其转换为Hemmington,然后在其中填充一棵树并遍历它,直到没有进一步遍历会导致更小的距离为止。我不知道这有多有效。
答案 1 :(得分:0)
我建议使用哈希集的简单方法。
如果哈希集实现良好且具有良好的哈希函数,则可以考虑在O(1)
中检查元素是否属于此集合。
然后,我们可以执行以下操作:
function find_closest_arrays(A, B_1, ..., B_n) {
result = [0, ..., 0] // array of size n
for elem in A {
for i in 1 ... n {
if elem is in B_i {
result[i] ++
}
}
}
return result
}
此函数返回一个数组result
。 result[i]
包含输入数组A
和B_i
之间共有的元素数。
从这里开始,k
的最佳表现是很快的,您要做的就是获取k
中最大的result
的索引。
此算法的时间复杂度为O(n * m)
,其中m
是输入数组的大小,而n
是数组集的大小。