私はこの機能を持っています
public int numberOfPossiblePairs(int n)
{
int k=2;
if (k>n-k) { k=n-k;}
int b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
}
これは、指定された数のアイテムから作成できるペアの数を取得します。たとえば、1000個のアイテムの配列がある場合、499,500ペアを作成できます。しかし、私が実際に必要としているのはその逆です。言い換えると、パラメーターとして499500を受け取り、その数のペアを生成できる一意のアイテムの元の数として1000を返す関数です。(499501のように、その数だけ一意のペアを作成する一意のアイテムの数がない不完全な番号も処理できる場合はボーナスになりますが、499500ペアを生成するため、最も近いものとして1000が返されます。)
探している番号が表示されるまで、numberOfPossiblePairs()を段階的にループできることに気付きましたが、そのようにブルートフォースするのではなく、アルゴリズムでこれを行う方法があるはずです。
あなたの問題は小さな代数に要約され、O(1)
時間内に解決することができます。最初に、関数はペアの順列の数ではなく、ペアの組み合わせの数を与えることに注意してください。いずれにせよ、以下のロジックは順列に対応するために簡単に変更できます。
組み合わせの数の式を書くことから始めますkを選択します。
n = 1000およびr = 2に設定すると、次のようになります。
1000! / (2!(998)!) = 1000 * 999 / 2 = 499500
と同じようにnumberOfPossiblePairs(1000)
。
演習に進むと、この例ではr = 2であるため、次のようになります。
total = n! / ((n - 2)! * 2!)
ここで単純化します。
total = (n * (n - 1)) / 2
total * 2 = n^2 - n
n^2 - n - 2 * total = 0
これで、2次方程式を適用してnを解くことができます。
ここで、x = n、a = 1、b = -1、およびc = -2 *合計があり、次のようになります。
n = (-(-1) +/- sqrt(1^2 - 4 * 1 * (-2 * total))) / 2
正の数のみに関心があるため、負の解は除外します。コードには次のようなものがあります(注:OPはJavaを使用しているようで、私はここでは専門家ではありません...以下はC++
):
int originalNumber(int total) {
int result;
result = (1 + std::sqrt(1 - 4 * 1 * (-2 * total))) / 2;
return result;
}
結果が整数でない場合に最も近い値を返すというボーナスの質問については、整数に強制変換する前に、結果を単純に丸めることができます。
int originalNumber(int total) {
int result;
double temp;
temp = (1 + std::sqrt(1 - 4 * 1 * (-2 * total))) / 2;
result = (int) std::round(temp);
return result;
}
ここで、のような値500050
が渡されると、実際の結果は1000.55
であり、上記はを返し1001
ますが、最初のソリューションはを返し1000
ます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加