簡體   English   中英

(算法)查找兩個未排序的數組在O(n)時間內是否有任何公共元素而沒有排序?

[英](Algorithm) Find if two unsorted arrays have any common elements in O(n) time without sorting?

我們有兩個未排序的數組,每個數組的長度為n。 這些數組包含0-n 100范圍內的隨機整數。 如何找出這兩個數組在O(n)/線性時間內是否有任何共同元素? 不允許排序。

Hashtable會救你。 真的,它就像算法的瑞士刀。
只需將第一個數組中的所有值放入其中,然后檢查第二個數組中是否存在任何值。

您尚未定義計算模型。 假設你只能在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)算法都不能讀取整個輸入,因此如果這些位重要則不作出反應。

回答Neil:既然你知道你的N是什么(兩個大小為N的數組),你可以創建一個數組大小為2 * N * some_ratio的散列(例如:some_ratio = 1.5)。 使用此大小,幾乎所有簡單的哈希函數都將為您提供良好的實體傳播。

您還可以實現find_or_insert以搜索現有或在同一操作中插入新的,這將減少散列函數和比較調用。 (c ++ stl find_or_insert不夠好,因為它沒有告訴你項目之前是否存在)。

線性測試

使用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)"}]

如果存儲不重要,則抓取哈希表以支持長度為n的數組。 當您在第一個數組中遇到該數字時,標記為true。 在傳遞第二個數組時,如果你發現它們中的任何一個是真的,那么你就得到了答案。 上)。

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;

將第一個數組的元素放在哈希表中,並檢查是否存在掃描第二個數組。 這為您提供了O(N)平均情況下的解決方案。

如果你想要一個真正的O(N)最壞情況解決方案,那么使用0-n ^ 100范圍內的線性數組而不是使用哈希表。 請注意,每個條目只需要使用一個位。

根據發布到日期的想法。我們可以將一個數組整數元素存儲到哈希映射中。 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";
   }
  }
 } 

我希望它有所幫助。

你嘗試過計數嗎? 它實現簡單,使用O(n)空間並且還具有\\ theta(n)時間復雜度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM