O(N) 解决方案(BloomFilters):
这是一个使用布隆过滤器的解决方案(实现来自 Guava 库)
public static <T> T findCommon_BloomFilterImpl(T[] A, T[] B, Funnel<T> funnel) {
BloomFilter<T> filter = BloomFilter.create(funnel, A.length + B.length);
for (T t : A) {
filter.put(t);
}
for (T t : B) {
if (filter.mightContain(t)) {
return t;
}
}
return null;
}
像这样使用它:
Integer j = Masking.findCommon_BloomFilterImpl(new Integer[]{12, 2, 3, 4, 5222, 622, 71, 81, 91, 10}, new Integer[]{11, 100, 15, 18, 79, 10}, Funnels.integerFunnel());
Assert.assertNotNull(j);
Assert.assertEquals(10, j.intValue());
在 O(N) 中运行,因为计算 Integer 的哈希非常简单。如果您可以将元素的哈希计算减少到 O(1) 或小的 O(K),那么仍然是 O(N),其中 K 是每个元素的大小。
O(N.LogN) 解决方案(排序和迭代):
排序和遍历数组将引导您获得 O(N*log(N)) 解决方案:
public static <T extends Comparable<T>> T findCommon(T[] A, T[] B, Class<T> clazz) {
T[] array = concatArrays(A, B, clazz);
Arrays.sort(array);
for (int i = 1; i < array.length; i++) {
if (array[i - 1].equals(array[i])) { //put your own equality check here
return array[i];
}
}
return null;
}
concatArrays(~)
当然是 O(N)。Arrays.sort(~)
是 QuickSort 的双轴实现,复杂度为 O(N.logN),再次遍历数组是 O(N)。
所以我们有 O((N+2).logN) ~> O(N.logN)。
作为一般情况下的解决方案(没有问题的“在 k 内”条件)比你的要好。在您的精确情况下,应该考虑 k “接近” N。