2つのセットが与えられ、線形時間でそれらの交差を計算するアルゴリズムはありますか?
2つのfor
ループを実行して、要素のすべてのペアをチェックし、両方のセットで見つかった要素を記録できます。ただし、実行時間はO(n2)。 O(n)時間でこれをどのように行うのですか?
これは、セットの実装によって異なります。
ハッシュセット(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)要素しかないためです。
ハッシュテーブルについて誰も触れなかったのではないでしょうか。
セットの実装に関係なく(ここでの「セット」が単純な配列を意味する場合でも)、次のことができます。
O(n)
_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つの配列を結合し、この結合された配列内の各要素の出現回数をカウントして、これらを新しい配列に配置します。次に、このカウント配列で2を含むエントリを確認します。これらの要素は2つのセットの交差部分にあります。
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は漸近平均であり、C
はconstant
であり、T(hash)
はハッシュ関数に必要な時間です
セット1のすべての要素について、その要素がセット2にあるかどうかを確認します。O(1)ルックアップ時間を償却したセットを実装できます。