線形時間インプレースリフルシャッフルアルゴリズムはありますか?これは、いくつかの特に器用な手が実行できるアルゴリズムです。偶数サイズの入力配列を均等に分割してから、2つの半分の要素をインターリーブします。
Mathworldには、リフルシャッフルに関する簡単なページがあります。特に、入力配列1 2 3 4 5 6を1 4 2 5 3 6に変換するout-shuffleに興味があります。定義では、入力長はことに注意してください。
サイズ以上の便利な2番目の配列がある場合、線形時間でこれを実行するのは簡単です。最初に最後の要素を配列にコピーします。次いで、0ベースのインデックスを仮定すると、最初のコピーインデックスから要素をに。次に、nをコピーします入力配列、マッピングインデックスに二番目の配列の後ろからの要素に。(入力の最初と最後の要素が移動しないため、それよりもわずかに少ない作業を行うことができます。)
これをインプレースで実行しようとする1つの方法は、順列をばらばらのサイクルに分解し、各サイクルに従って要素を再配置することです。繰り返しますが、0ベースのインデックス付けを想定すると、6要素の場合に含まれる順列は
予想どおり、最初と最後の要素は固定小数点であり、中間の4つの要素を入れ替えると、期待される結果が得られます。
残念ながら、順列の数学(およびその)はほとんどウィキペディアに基づいており、これが線形時間で行えるかどうかはわかりません。このシャッフルに含まれる順列はすぐに分解できるのでしょうか?また、完全な分解も必要ありません。それぞれの要素からサイクルを再構築できるため、互いに素なサイクルのそれぞれの単一の要素を決定するだけで十分です。たぶん、まったく異なるアプローチが必要です。
関連する数学の優れたリソースは、アルゴリズムと同じくらい価値があります。ありがとう!