タスクは明らかに、必要な数のリストの長さNでO(1)であるアルゴリズムを見つけることです。したがって、上位100の番号または10000の番号が必要かどうかは関係ありません。挿入時間はO(1)になります。
ここでの秘trickは、リストの挿入に関してそのO(1)要件が言及されているが、質問は整数空間での検索時間の順序については何も言わなかったが、これはO(1)同じように。その場合の解決策は次のとおりです。
キーの数値と値のリンクリストポインターのペアを含むハッシュテーブルを用意します。ポインタの各ペアは、リンクリストシーケンスの開始と終了です。これは通常、次の要素の1つの要素になります。リンクされたリスト内のすべての要素は、次に大きい番号の要素の隣に移動します。したがって、リンクリストには、必要な番号のソートされたシーケンスが含まれます。最小の番号のレコードを保持します。
ランダムストリームから新しい数値xを取得します。
最後に記録された最低数よりも高いですか?はい=>ステップ4、いいえ=>ステップ2
取得した数字でハッシュテーブルをヒットします。エントリーはありますか?はい=>ステップ5。
ハッシュテーブルから取得したばかりのリスト要素を使用して、リンクリストの要素の直後に新しい番号を挿入します(そしてハッシュを更新します)。
記録された最小の番号lを取得します(そしてハッシュ/リストから削除します)。
取得した数字でハッシュテーブルをヒットします。エントリーはありますか?はい=>ステップ8。いいえ=>新しい数値l + 1を取得して、このステップを繰り返します(これは単純な上向き線形検索です)。
ポジティブヒットの場合、数値は新しい最低の数値になります。ステップ2に進む
重複する値を許可するために、ハッシュは実際には、重複する要素のリンクリストシーケンスの開始と終了を維持する必要があります。したがって、指定されたキーで要素を追加または削除すると、指す範囲が増減します。
ここでの挿入はO(1)です。言及されている検索は、O(数値間の平均差)のようなものだと思います。平均差は、数値スペースのサイズとともに増加しますが、数値リストの必要な長さとともに減少します。
したがって、数値スペースが大きい場合(たとえば、4バイトのint型、0〜2 ^ 32-1)、N = 100の場合、線形検索戦略はかなり貧弱です。このパフォーマンスの問題を回避するために、ハッシュテーブルの並列セットを保持できます。この場合、適切なキーを作成するために、数値がより大きな数値(1秒、10秒、100秒、1000秒)に丸められます。このようにして、ギアを上げ下げして、必要な検索をより迅速に実行できます。パフォーマンスはO(log numberrange)になると思いますが、これは一定、つまりO(1)でもあります。
これを明確にするために、197番を手に入れると想像してください。'190'で10のハッシュテーブルをヒットすると、最も近い10に丸められます。何か?いいえ。だから、120と言うまで10秒でダウンします。1秒のハッシュテーブルで129から始めて、何かをヒットするまで128、127を試すことができます。リンクリストのどこに番号197を挿入するかがわかりました。それを入力しながら、1のハッシュテーブルを197のエントリで更新し、10のハッシュテーブルを番号190、100で100などに更新する必要があります。ここで行う必要があるのは、番号範囲のログの10倍です。
詳細の一部は間違っていたかもしれませんが、これはプログラマーのやり取りであり、コンテキストはインタビューであったため、上記がその状況に十分な説得力のある答えであることを願っています。
編集並列ハッシュテーブルスキームと、それがどのように私が言及した貧弱な線形検索をO(1)検索に置き換えることができるかを説明するために、ここにいくつかの詳細を追加しました。もちろん、次に小さい番号のハッシュテーブルを調べて次の要素に進むことで、その番号に直接進むことができるため、次に小さい番号を検索する必要がないことにも気付きました。