![](/img/trans.png)
[英](Algorithm) Find if two unsorted arrays have any common elements in Θ(n*logn) time without sorting?
[英](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.