JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで一意な数字のみで構成されるn桁までの数字を数える方法


問題

JavaScriptで次のような関数を実装することを考えます。引数として数値 num を1つだけ受け取り、「num桁までの数字の中で、すべての桁が一意(重複なし)であるもの」の個数を返します。

例えば、関数への入力が次の場合:

const num = 1;

出力は次のようになります:

const output = 10;

出力の説明

0、1、2、3、4、5、6、7、8、9 の10個の数字は、いずれも1桁であり、それぞれに数字の重複がないためです。

実装例

const num = 1;
const uniqueDigits = (num = 1) => {
    const dp = [1, 10];
    const sum = [1, 11];
    for (let i = 2; i <= num; i++) {
        dp[i] = sum[i - 1] + (10 - i) * (dp[i - 1]);
        sum[i] = sum[i - 1] + dp[i];
    };
    return dp[num];
};
console.log(uniqueDigits(num));
console.log(uniqueDigits(2));
console.log(uniqueDigits(3));

コードの解説

この実装では動的計画法(Dynamic Programming)を採用しています。すでに計算済みの小さな桁数の結果を再利用することで、すべてを数え直すことなく効率的に答えを求められるのがポイントです。

  • dp:dp[i] に「i桁までの、すべての桁が一意な数字の総数」を格納します。初期値は dp[0] = 1、dp[1] = 10 です。
  • sum:dp の累積和を保持する補助配列で、漸化式の計算に使用されます。
  • 漸化式:桁を追加していくたびに使える残りの数字の選択肢が減っていくため、その減少分を係数 (10 - i) として反映しています。

処理はループを1回回すだけなので、時間計算量は O(n) と非常に効率的です。

実行結果

コンソールには次のように出力されます:

10
91
739
  • num = 1 の場合:0〜9 の10個
  • num = 2 の場合:1桁と2桁を合わせて91個(例:12、43 など。ただし 11 や 22 のように同じ数字が並ぶものは除外)
  • num = 3 の場合:3桁までを合わせて739個

  1. C++で一意の桁(重複しない数字)を持つ数を数える方法

    負でない整数 n が与えられたとき、0 以上 10n 未満の範囲に存在する「すべての桁が一意(重複なし)」である数 x の個数を求める問題を考えてみましょう。例えば n = 2 の場合、0 から 100 未満までの数のうち、11、22、33、44、55、66、77、88、99 のように同じ数字が重複している数を除外した個数、つまり 91 が答えとなります。解法のアプローチこの問題は、桁ごとに選べる数字の組み合わせを順番にかけていくことで効率的に解くことができます。手順は以下の通りです。n が 0 の場合は 1 を返します(0 のみが該当するため)。n は最大でも 10 桁しか考慮できないため、

  2. C++でN未満のすべての数を最大2種類の一意な数字で出力する方法

    この問題では、整数Nが与えられ、N未満のすべての数のうち、最大2種類の異なる数字(ユニークな数字)のみを使用して構成される数を出力します。つまり、1つの数を作るために使える数字の種類は最大2つまでという制限があります。問題を理解するために、具体例を見てみましょう。入力: N = 17 出力: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16この例では、17未満の数はすべて1種類または2種類の数字で構成されているため、すべてが出力対象となります。解法のアプローチこの問題を解くには、2種類のユニークな数字のみで構成されるすべての数を生成します。数の生成プロセスは0から始