2008-11-23 42 views
12

鑑於集列表集:算法合併共享至少2個元素

  • S_1:[1,2,3,4]
  • S_2:[3,4,5,6, 7]
  • S_3:[8,9,10,11]
  • S_4:[1,8,12,13]
  • S_5:[6,7,14,15,16,17]

什麼最e合併所有共享至少兩個元素的集合的方法很簡單嗎?我想這與連接組件問題很相似。因此,結果將是:

  • [1,2,3,4,5,6,7,14,15,16,17](S_1 UNION S_2 UNION S_5)
  • [8,9 10,11]
  • [1,8,12,13](S_4股1 S_1,和8 S_3,但不被合併,因爲它們只共享在每一個元件)

樸素實施O(N^2),其中N是集合的數量,這對我們來說是行不通的。這需要對數百萬套有效。

+0

集合中的值的範圍是多少? – 2008-11-23 20:35:01

+0

有沒有整數?他們可以在一套內重複嗎? – EvilTeach 2008-11-23 20:38:08

+0

集合中的值是整數,並且它們不在每個集合中重複 – bajafresh4life 2008-11-23 20:47:32

回答

3
Let there be a list of many Sets named (S) 

Perform a pass through all elements of S, to determine the range (LOW .. HIGH). 

Create an array of pointer to Set, of dimensions (LOW, HIGH), named (M). 

do 
    Init all elements of M to NULL. 

    Iterate though S, processing them one Set at a time, named (Si). 

     Permutate all ordered pairs in Si. (P1, P2) where P1 <= P2. 
     For each pair examine M(P1, P2) 
      if M(P1, P2) is NULL 
       Continue with the next pair. 
      otherwise 
       Merge Si, into the Set pointed to by, M(P1, P2). 
       Remove Si from S, as it has been merged. 
       Move on to processing Set S(i + 1) 

     If Si was not merged, 
      Permutate again through Si 
      For each pair, make M(P1, P2) point to Si. 

while At least one set was merged during the pass. 

我的頭說,這是關於訂單(2N LN N)。 帶上一粒鹽吧。

2

如果您可以訂購集合中的元素,則可以在集合上使用Mergesort進行查看。所需的唯一修改是在合併階段檢查重複項。如果找到一個,只需丟棄重複。由於mergesort是O(n * log(n)),與天真的O(n^2)算法相比,這將提供更快的速度。

但是,爲了真正有效,您應該維護一個已排序的集合並對其進行排序,以便您可以跳過排序階段並直接進入合併階段。

1

一面注意:這取決於發生的頻率。如果大多數對集合至少共享兩個元素,那麼在逐步比較時同時構建新集合可能最有效,如果它們與條件不匹配,則將其丟棄。如果大多數對不是至少共享兩個元素,則推遲構建新組,直到確認條件可能更有效。

0

如果你的元素本質上是數值型的,或者可以自然排序(即你可以指定一個值,如1,2,42等),我會建議在合併集上使用基數排序,並進行第二輪挑​​選獨特的元素。

該算法應該是O(n),並且您可以使用按位移位運算符和位掩碼相當多地優化基數排序。我爲我正在進行的一個項目做了類似的事情,它的作用就像一個魅力。

1

我不明白如何在小於O(n^2)的情況下完成此操作。

每一組都需要與其他組進行比較,看它們是否包含2個或更多的共享元素。這就是n *(n-1)/ 2比較,因此O(n^2),即使對共享元素的檢查需要一定的時間。

在排序中,天真的實現是O(n^2),但是您可以利用有序比較的傳遞性質(例如,您不知道快速排序的較低分區中什麼都不需要與任何東西進行比較在上面的分區中,因爲它已經與支點進行了比較)。這就是排序結果爲O(n * log n)的原因。

這不適用於此。所以除非這些集合有什麼特別之處,讓我們可以根據以前的比較結果來跳過比較,否則一般會是O(n^2)。

Paul。

相關問題