web-dev-qa-db-ja.com

5つの並べ替えられた配列の中央値

5つの並べ替えられた配列の中央値のソリューションを見つけようとしています。これはインタビューの質問でした。

5つの配列をマージし、中央値[O(l + m + n + o + p)]を見つけることは、私が考えることができる解決策でした。

同じサイズの2つの並べ替えられた配列の場合、log(2n)でそれを実行できることを知っています。 [両方の配列の中央値を比較し、各配列の半分を捨てて、プロセスを繰り返す]。 ..ソートされた配列で中央値を見つけることは一定の時間になる可能性があります..したがって、これはlog(n)ではないと思いますか? ..これの時間の複雑さは何ですか?

1] 5つのアレイに対して同様のソリューションはありますか?配列が同じサイズの場合は、より良い解決策はありますか?

2]これは5を要求されたので、N個の並べ替えられた配列にいくつかの解決策があると思いますか?

ポインタをありがとう。

私が面接担当者に尋ねたいくつかの説明/質問:
配列は同じ長さですか
=>いいえ
配列の値に重複があると思います
=>はい

演習として、2つの配列のロジックは拡張されないと思います。ここに試してみます:
上記の2つの配列のロジックを適用して3つの配列と言います:[3,7,9] [4,8,15] [2,3,9] ...中央値7,8,3
要素を投げる[3,7,9] [4,8] [3,9] ..中央値7,6,6
要素を投げる[3,7] [8] [9] ..中央値5,8,9 ...
要素を投げる[7] [8] [9] ..中央値= 8 ...これは正しくないと思われますか?

ソートされた要素のマージ=> [2,3,4,7,8,9,15] =>期待される中央値= 7

43
codeObserver

(これは、2つのアレイに対するアイデアの一般化です。)

5つのアレイの5つの中央値から始めると、明らかに、全体の中央値は5つの中央値の最小値と最大値の間でなければなりません。

証明は次のようになります。aが中央値の最小値であり、bが中央値の最大値である場合、各配列の要素の半分未満がa未満で、要素の半分未満がbより大きいです。結果は次のとおりです。

したがって、aを含む配列では、a未満の数値を破棄します。 bを含む配列では、bより大きい数値を破棄します。ただし、両方の配列から同じ数の要素のみを破棄します。

つまり、aが配列の先頭からj個の要素であり、bが配列の末尾からk個の要素である場合、aの配列から最初のmin(j、k)要素と最後のmin(j、k)要素を破棄します)bの配列の要素。

要素の合計が1または2になるまで繰り返します。

これらの各操作(つまり、並べ替えられた配列の中央値を見つけ、配列の最初または最後からk個の要素を捨てる)は一定の時間です。したがって、各反復は一定の時間です。

反復ごとに少なくとも1つの配列から要素の半分以上(以上)が捨てられ、5つの配列のそれぞれに対してlog(n)回しか実行できません...したがって、全体的なアルゴリズムはlog(n)です。

[更新]

Himadri Choudhuryがコメントで指摘しているように、私の解決策は不完全です。気になる詳細やコーナーケースがたくさんあります。だから、少し肉付けするために...

5つの配列Rのそれぞれについて、「下中央値」をR [n/2-1]として定義し、「上中央値」をR [n/2]として定義します。ここで、nは配列内の要素の数(および配列)は0からインデックス付けされ、2で除算されます。

「a」を下の中央値の最小値、「b」を上の中央値の最大値とします。最小の中央値が最小の配列が複数あるか、最大の中央値が最大の配列が複数ある場合は、異なる配列からaとbを選択します(これは、これらのコーナーケースの1つです)。

今、ヒマドリの提案を借りて:配列からおよび含む aまでのすべての要素を消去し、配列からおよび含む bまでのすべての要素を消去します。両方の配列の要素数。 aとbが同じ配列にある可能性があることに注意してください。しかし、そうであれば、それらは同じ値を持つことができませんでした。そうでなければ、別の配列からそれらの1つを選択することができたでしょう。したがって、この手順が終了して、同じ配列の最初と最後から要素を破棄しても問題ありません。

3つ以上の配列がある限り、繰り返します。ただし、配列が1つまたは2つになったら、包括的ではなく排他的になるように戦略を変更する必要があります。 含まない aまで、および含まない bまでを消去します。残りの1つまたは2つの配列の両方に少なくとも3つの要素がある限り、このように続行します(進行を保証します)。

最後に、いくつかのケースに削減します。最も難しいのは、残りの2つの配列で、そのうちの1つは1つまたは2つの要素を持っています。ここで、「並べ替えられた配列と1つまたは2つの追加の要素を与え、すべての要素の中央値を見つける」と尋ねた場合、一定の時間でそれを実行できると思います。 (繰り返しますが、詳細を説明するためにたくさんの詳細がありますが、基本的な考え方は、1つまたは2つの要素を配列に追加しても、「中央値を押し出す」ことはあまりないということです。)

26
Nemo

5つのアレイを完全にマージする必要はありません。 (l + n + o + p + q)/ 2要素になるまでマージソートを実行して、中央値を得ることができます。

1
karmakaze

5つの配列に同じアイデアを適用するのはかなり簡単です。

まず、質問をより一般的な質問に変換します。 N個の並べ替えられた配列でK番目の要素を見つける

  1. バイナリ検索でソートされた各配列から(K/N)番目の要素を検索します。たとえば、K1、K2 ... KN

  2. Kmin = min(K1 ... KN)、Kmax = max(K1 ... KN)

  3. Kmin未満またはKmaxより大きいすべての要素を破棄します。たとえば、X要素が破棄されたとします。

  4. 残りの要素を含むソートされた配列で(K-X)番目の要素を見つけることにより、プロセスを繰り返します

1
Ryan Ye