web-dev-qa-db-ja.com

セットの交点を線形時間で計算していますか?

2つのセットが与えられ、線形時間でそれらの交差を計算するアルゴリズムはありますか?

2つのforループを実行して、要素のすべてのペアをチェックし、両方のセットで見つかった要素を記録できます。ただし、実行時間はO(n2)。 O(n)時間でこれをどのように行うのですか?

36
NEO

これは、セットの実装によって異なります。

ハッシュセット(O(1)ルックアップ)がある場合、他のすべての投稿者が示すアプローチは正しいです。最初のセットのすべての要素を反復処理します。 2番目のセットにある場合は、結果に追加します。これはO(n)時間で実行されます。

ツリーセット(O(lg n)ルックアップ)がある場合、このアプローチは機能しますが、O(n lg n)時間で実行されます。あなたはもっとうまくできる。 O(n)解があります。2つのセットの要素を昇順でトラバースできるある種のイテレータがあると思います。そうすると、質問は「与えられた2これは、2つの範囲をマージするために使用するアルゴリズムの修正バージョンを使用して行うことができます。2つの反復子を追跡するのがアイデアです。各ステップで、範囲の最初の要素を比較します。等しい場合は、要素を交差点に追加し、両方のイテレータを前方に進めます。最初の要素が2番目のイテレータよりも小さい場合は、最初のイテレータを進めます。最初の要素が大きい場合は、2番目のイテレータを進めます。これは、時間O(n)各反復は少なくとも1つの要素を消費し、合計O(n)要素しかないためです。

41
templatetypedef

ハッシュテーブルについて誰も触れなかったのではないでしょうか。
セットの実装に関係なく(ここでの「セット」が単純な配列を意味する場合でも)、次のことができます。

  1. 最初のセットの内容をハッシュテーブルに入れ、
  2. 2番目のセットを反復処理し、ハッシュテーブルに現在の要素が含まれているかどうかを確認します。

O(n)

9
Nikita Rybak
_intersection(a, b):
  result = new empty set
  for x in b:
    if a contains x:
      add x to result

  return result
_

containsテストが一定の時間である場合(ハッシュテーブルを実装として使用するセットなど)、このアルゴリズムはO(n)です。

2
sjr

2つの配列を結合し、この結合された配列内の各要素の出現回数をカウントして、これらを新しい配列に配置します。次に、このカウント配列で2を含むエントリを確認します。これらの要素は2つのセットの交差部分にあります。

2
user2603796

2つのリストのいずれかが順序付けられている場合、順序付けられていないリストから始めることができます

_FUNCTION: INTERSECTION ( LIST A, LIST B )
{
   CREATE C AS EMPTY LIST

   FOR EVERY: NUMBER n IN A
   {
        IF BINARY-SEARCH(n) IN B
        {
            ADD n TO C
        }
   }

   RETURN C
}
_

Time Complexity = O(n O(BINARY-SEARCH)) = O(n log n)

リストBがhashedの場合、BIG-THETA(C n + T(hash))

ここで、BIG-THETAは漸近平均であり、Cconstantであり、T(hash)はハッシュ関数に必要な時間です

0

セット1のすべての要素について、その要素がセット2にあるかどうかを確認します。O(1)ルックアップ時間を償却したセットを実装できます。

0
Anon.