私は最近のインタビューでこの問題に直面しました:
範囲内に着信番号のストリームがあり0 to 60000
、その範囲から番号を取得し、その瞬間までのその番号の発生回数を返す関数があります。このシステムを実装するための適切なデータ構造/アルゴリズムを提供します。
私の解決策は次のとおりです。
ビットベクトルを指すサイズ60001の配列を作成します。これらのビットベクトルには、着信番号のカウントが含まれ、着信番号は、対応する番号の配列にインデックスを付けるためにも使用されます。ビットベクトルは、カウントが大きくなりすぎて保持できないため、動的に増加します。
したがって、その数が一定の割合で発生している場合、100numbers/sec
100万年後には合計数は=になります(100*3600*24)*365*1000000 = 3.2*10^15
。ストリーム内のすべての番号が同じである最悪の場合ceil((log(3.2*10^15) / log 2) )= 52bits
、番号が均一に分散されている場合、番号(3.2*10^15) / 60001 = 5.33*10^10
ごとに出現回数があり、番号ごとに合計が必要になり36 bits
ます。したがって、4バイトのポインタ(60001 * 4)/1024 = 234 KB
が配列用のメモリを必要とし、同じ番号の場合は、ビットベクトルサイズ=が必要です52/8 = 7.5 bytes
。これはまだ約234KBです。また、他のケースでは、(60001 * 36 / 8)/1024 = 263.7 KB
合計約500KBのビットベクトルが必要です。したがって、通常のPCとメモリを使用してこれを行うことは非常に実行可能です。
しかし、インタビュアーは、それは無限のストリームであるため、最終的にはオーバーフローし、PCが多数あり、それらの間でメッセージを渡したり、ファイルシステムなどについて考えることができる場合、どうすればこれを行うことができるかについてのヒントを私に与えました。しかし、私はこの解決策かどうかを考え続けましたその時は機能していませんでしたが、他の人も機能していました。言うまでもなく、私はその仕事に就けませんでした。
より少ないメモリでこの問題を解決するにはどうすればよいですか?別のアプローチを考えられますか(PCのネットワークを使用する場合があります)?