我们有两个未排序的数组,每个数组的长度为n。这些数组包含在0-n100范围内的随机整数。如何在O(n)/线性时间内查找这两个数组是否具有任何公共元素?不允许排序。
我们有两个未排序的数组,每个数组的长度为n。这些数组包含在0-n100范围内的随机整数。如何在O(n)/线性时间内查找这两个数组是否具有任何公共元素?不允许排序。
Hashtable 将会拯救你。真的,它就像算法中的瑞士军刀。
只需将第一个数组中的所有值放入其中,然后检查第二个数组中是否存在任何值。
n
定义为输入数组的“长度”,而不是它占用的内存单元数。你不能用n个内存单元存储100 log n位数字的2n个数字。 - meriton线性测试
使用Mathematica哈希函数和任意长度整数。
测试直到 n=2^20,生成随机数直到(2^20)^100 = (约10^602)。
为了防止误解...程序如下:
k = {};
For[t = 1, t < 21, t++,
i = 2^t;
Clear[a, b];
Table[a[RandomInteger[i^100]] = 1, {i}];
b = Table[RandomInteger[i^100], {i}];
Contains = False;
AppendTo[k,
{i, First@Timing@For[j = 2, j <= i, j++,
Contains = Contains || (NumericQ[a[b[[j]]]]);
]}]];
ListLinePlot[k, PlotRange -> All, AxesLabel -> {"n", "Time(secs)"}]
a[b[j]]
需要 O(log n) 步骤,因为 b[j] 包含 O(log n) 位数字。平均而言,b 中的第一个重复项出现在位置 n/2。实际上,在您的示例中,列表之间可能没有重复项,因此在失败之前必须遍历整个列表。无论图表显示什么,对我来说都像是 O(n log n)。 - President James K. PolkDefine largeArray(n)
// First pass
for(element i in firstArray)
largeArray[i] = true;
// Second pass
Define hasFound = false;
for(element i in secondArray)
if(largeArray[i] == true)
hasFound = true;
break;
#!/usr/bin/perl
use strict;
use warnings;
sub find_common_elements{ # function that prints common elements in two unsorted array
my (@arr1,@array2)=@_; # array elements assumed to be filled and passed as function arguments
my $hash; # hash map to store value of one array
# runtime to prepare hash map is O(n).
foreach my $ele ($arr1){
$hash->{$ele}=true; # true here element exists key is integer number and value is true, duplicate elements will be overwritten
# size of array will fit in memory as duplicate integers are ignored ( mx size will be 2 ^( 32) -1 or 2^(64) -1 based on operating system) which can be stored in RAM.
}
# O(n ) to traverse second array and finding common elements in two array
foreach my $ele2($arr2){
# search in hash map is O(1), if all integers of array are same then hash map will have only one entry and still search tim is O(1)
if( defined $hash->{$ele}){
print "\n $ele is common in both array \n";
}
}
}
希望它有所帮助。