具体的な質問は次のとおりです。
1 ~ 9 から N 個の数字を選択して、繰り返しのない N 桁の数字を形成し、小さいものから大きいものまで番号を付けます。M の数字のいずれかを入力すると、番号は
の番号に対応します。たとえば、N=3、M=213 出力: [123(1), 132(2), 213(3), 231(4), 312(5), 321(6)]--->X =2
この質問を見て最初に考えたのは、最小から最大まで完全に配置された配列を生成し、その配列を走査して対応するシリアル番号 (配列の添え字に 1 を加えたもの) を取得することでした。それぞれを最小から最大まで考えて、配列にプッシュを生成し、その数値が現在の質問で指定された数値であるかどうかを判断します。そうである場合、必要なシーケンス番号は現在の配列の長さよりも優れています。前者は、後続の項目を計算して生成するために時間を無駄にする必要がないことです。生成自体の複雑さは高くありませんが、16 進数または 16 進数に拡張して大きな数値を指定すると、未使用のデータを保存するためにスペースが無駄になります。生成を必要としない他の方法を試してみることもできるかもしれません。
まず、数値 N が与えられた場合、M は 1 から N までの N 桁で構成されます (たとえば、N=4 の場合、M は他の 1349 桁ではなく 1234 桁で構成されます)。他の組み合わせも可能です)。その理由は、共通点を分析して問題の解決策を得るために条件を単純化する必要があり、ランダムな状況から理想的な状況に変換することは難しくないため、この記事は長くなりません。 。まず、質問で示された例を分析しましょう。 [123(1), 132(2), 213(3), 231(4), 312(5), 321(6)] 213 は 3 桁目で、最初の数字は 2 です。つまり、最初の数字が 1 であるものはすべてその前にあります (123,132)。2 番目の数字と次の数字 13 の組み合わせを見てみましょう。最初の文字 1 はすでに最小です。その前に数字を置くことはできません。3 番目の数字を調べる必要はありません。前の数字が決定されている場合、最後の数字の可能性は 1 つだけであるため、結果として 213 が前に付けられます。 2 (最初の桁) 0 (2 桁目) 0 (最後の桁) )= 2 つの数字、つまり現在の数字は 3 桁目にあります。比較して、他の数字を分析すると、確かに答えは次のようになります。同じです。このことから、特定の桁が現在の数値より小さい可能性の総数を計算し、合計して 1 を得る関数 (つまり、以下のコードの setAll()) が必要であると結論付けることができます。コードの実装を参照してください: