みんながテーブルの周りを時計回りに話すミーティングを開催します。 n個のスポットを持つn人がいます。それぞれの人には位置の好みがあります(たとえば、最初に行きたい人、最後に行きたい人など)。全員がランダムに着席し、自分の位置から移動することはできません。ほとんどの人を満足させるために、テーブル上の最適な開始位置をどのように計算しますか?
O(n ^ 2)ソリューションがあります。開始位置として1..nの各位置を想定した場合に満足する人の数を確認します。次に、最大値を与えた位置を返します。
かなり単純なO(n)アルゴリズムが存在します:
pos
を配列とすると、座席i
の人がn
-番目として話したい場合、エントリpos[i] = n
があります。座席の番号付けが始まる場所は関係ありません。 i
とn
の両方がゼロからカウントを開始します。
違いi - pos[i]
は、座席i
の人が満足するためにラウンドを開始する必要がある座席です。 satisfied
配列の開始位置ごとに満足している人を数えます。次に、その配列の最大値を見つけることができます。最大値のインデックスは、最大の満足度を得るためにラウンドを開始する必要があるシートです。
Javaの例:
int findBestStart(int[] pos) {
// ask each seat where they'd like to start
int[] satisfied = new int[pos.length];
for (int i = 0; i < pos.length; i++) {
int start = i - pos[i]
if (start < 0) start += pos.length;
satisfied[start]++;
}
// find where most would like to start
int bestSeat = -1;
int bestSatisfied = -1;
for (int i = 0; i < satisfied.length; i++) {
if (satisfied[i] > bestSatisfied) {
bestSeat = i;
bestSatisfied = satisfied[i];
}
}
return bestSeat;
}
各人が自分が入りたい順番を正確に知っていて、座席の順番が一定である場合、各人は自分が話し始めたい開始位置を知っています。このようにして、特定のポイントから開始して話したい人の数を計算できます。これは、配列へのインデックスとして優先する位置の場合、複雑さはO(n)です。