(算法)查找两个未排序的数组在O(n)时间内是否有任何公共元素而没有排序?

时间:2010-12-28 16:17:55

标签: arrays algorithm

我们有两个未排序的数组,每个数组的长度为n。这些数组包含0-n 100 范围内的随机整数。如何找出这两个数组在O(n)/线性时间内是否有任何共同元素?不允许排序。

8 个答案:

答案 0 :(得分:11)

Hashtable会救你。真的,它就像算法的瑞士刀 只需将第一个数组中的所有值放入其中,然后检查第二个数组中是否存在任何值。

答案 1 :(得分:6)

您尚未定义计算模型。假设你只能在O(1)时间内读取O(1)位(其他任何东西都是一个相当奇特的计算模型),那么就没有算法可以解决O(n)最坏情况时间复杂度的问题。

证明草图: 输入中的每个数字取O(log(n ^ 100))= O(100 log n)= O(log n)位。因此整个输入为O(n log n)位,在O(n)时间内无法读取。因此,任何O(n)算法都不能读取整个输入,因此如果这些位重要则不作出反应。

答案 2 :(得分:2)

回答尼尔: 由于您在开始时就知道您的N(两个大小为N的数组),您可以创建一个数组大小为2 * N * some_ratio的哈希(例如:some_ratio = 1.5)。使用此大小,几乎所有简单的哈希函数都将为您提供良好的实体传播。

您还可以实现find_or_insert以搜索现有或在同一操作中插入新的,这将减少散列函数和比较调用。 (c ++ stl find_or_insert不够好,因为它没有告诉你该项目之前是否存在)。

答案 3 :(得分:2)

线性测试

使用Mathematica哈希函数和任意长度的整数。

alt text

测试直到 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)"}]

答案 4 :(得分:1)

如果存储不重要,则抓取哈希表以支持长度为n的数组。当您在第一个数组中遇到该数字时,标记为true。在传递第二个数组时,如果你发现它们中的任何一个是真的,那么你就得到了答案。为O(n)。

Define 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;

答案 5 :(得分:1)

将第一个数组的元素放在哈希表中,并检查是否存在扫描第二个数组。这为您提供了O(N)平均值的解决方案。

如果你想要一个真正的O(N)最坏情况解决方案,那么使用0-n ^ 100范围内的线性数组而不是使用哈希表。请注意,每个条目只需要使用一个位。

答案 6 :(得分:0)

你试过counting sort吗?它易于实现,使用O(n)空间并且还具有\ theta(n)时间复杂度。

答案 7 :(得分:0)

基于发布到日期的想法。我们可以将一个数组整数元素存储到哈希映射中。 RAM中可以存储不同整数的最大数量。哈希映射只有唯一的整数值。重复项被忽略。

以下是Perl语言的实现。

#!/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";
   }
  }
 } 

我希望它有所帮助。