O(k)メモリO(n)時間のみを使用して、指定されたシーケンスからk番目に小さい要素を見つける


11

一連のn数値を1つずつ読み取るとします。O k セルメモリを使用して線形時間(O n )でk番目に小さい要素を見つける方法。私たちは最初に保存すべきだと思うk個のシーケンスの条件をして取得するときのk + 1番目の用語を、私たちは必ずそれができないことを期削除のk番目に小さい要素[保存" のk + 1番目の用語を。したがって、各ステップでこの使用できない用語を示すインジケーターが必要であり、このインジケーターは各ステップですばやく更新される必要があります。「マックス」から始めましたO(k)O(n)kk+1kk+1; しかし、迅速に更新することはできません。つまり、maxを考慮した場合、最初の削除ではmaxを逃し、線形ではないO(k)とその原因(nk)×O(k)時間でmaxを検索する必要があります。おそらく、シーケンスの最初のk項をよりインテリジェントに保存する必要があります。

この問題を解決するにはどうすればよいですか?


1
あなたはオンラインアルゴリズムに興味がありますか、それとも他のアルゴリズムがしませんか?
Yuval Filmus

もしk=θ(n)、あなたは順序統計アルゴリズムを使用することによってそれを行うことができます。場合はk=o(n)、その後、あなたはそれを行うことができますO(k)メモリとO(nlogk)任意の高さバランスの木を使用して時間を。
Shreesh 2017年

これは選択問題と呼ばれますen.wikipedia.org/wiki/Selection_algorithm
xavierm02

グーグルできる線形時間インプレースアルゴリズムがありますが、それらはやや複雑です。
Yuval Filmus

@ xavierm02同じ選択問題ではありません。メモリ制限の制約があるためです。
Shahab_HK 2017年

回答:


16

サイズバッファーを作成します。配列から2 k要素を読み込みます。線形時間選択アルゴリズムを使用 て、k個の最小要素が最初になるようにバッファーを分割します。これにはO k 時間かかります。ここで、配列から別のkアイテムをバッファーに読み込み、バッファー内の最大のkアイテムを置き換え、以前のようにバッファーを分割し、繰り返します。2k2kkO(k)kk

これには、時間とO k 空間が必要です。O(kn/k)=O(n)O(k)


+1、これは尋ねられた漸近に適合します。そうは言っても、これが単一の線形時間選択アルゴリズムを実行するよりも速いとは思いません... が小さな定数である場合を除いて、興味深い見方を提供します。たとえば、k = 1の場合、このアルゴリズムは関数を生成します。kk=1min
orlp

1
時々、線形時間選択アルゴリズムはスペースを使いすぎます。たとえば、ストリーミングコンテキストでの使用や、入力配列が不変である場合には適していません。
jbapple

それらは有効なポイントです。
orlp

3

あなたがそれを行うことができメモリとO N ログkは最初から固定サイズの最大ヒープを形成することにより、時間k個の要素O K 、配列の残りの部分にわたって反復し、新しいを押し、時間要素、次に要素ごとにO log k をポップして、合計時間O k + n log k = O n log k )を求めますO(k)O(nlogk)kO(k)O(logk)O(k+nlogk)O(nlogk)

中央値中央値選択アルゴリズムを使用してkで選択し、最初のk要素を返すことにより、補助メモリとO n 時間でそれを行うことができます。漸近線を変更せずに、introselectを使用して平均的なケースを高速化できます。これは、問題を解決するための標準的な方法です。O(logn)O(n)kk

現在、技術的にはO k は比較できません。ただし、O log n は実際にはより良いと主張します。これは、2 64バイトを超えるメモリ(log 2 64 = 64)を超えるコンピューターシステムがないことを考えると、実質的に一定であるためです。一方、knと同じくらい大きくなることがあります。O(logn)O(k)O(logn)264log264=64kn


ヒープが興味深いときに使用する順序を逆にすることで、ヒープベースのアルゴリズムの複雑さを改善できることに注意してください。O(n×logmin(k,nk))
xavierm02

@ xavierm02 =。証明:の最悪のケースはです。の最悪のケースはです。これらは定数係数内では同じなので、 =です。O k k n m i n k n k nO(min(k,nk))O(k)knmin(k,nk) OminknkOkn2O(min(k,nk))O(k)
orlp

@ xavierm02とはいえ、それでも素晴らしいスピードアップです:)
orlp

un,k=kはが、はありません。そうだとしましょう。次に、とがいくつかあるので、すべての、、これは明らかに偽です(とることができるため したがって、です。O(k)O(min(k,nk))CMMknkC(nk)n=k+).O(min(k,nk))O(k)
xavierm02

@ xavierm02私はあなたの表記に慣れていません。公平を期すために、私は一般に多次元のビッグ表記に慣れていません。特に、次元は無関係ではないことを考えると、un,kOn,k
orlp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.