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

Pythonで各桁が厳密に増加するn桁の整数の個数を求めるプログラム

整数 n が与えられたとき、各位の数字が左から右へ厳密に増加している(隣り合う桁が必ず大きくなっている)n 桁の正の整数が何個存在するかを求めます。

たとえば入力が n = 3 の場合、出力は 84 となります。該当するのは 123、124、125、…、678、789 のような数です。

解き方のポイント

この問題は、組み合わせ(コンビネーション)の考え方を使うと非常にシンプルに解けます。

使用できる数字は 1〜9 の 9 種類です。この中から n 個の異なる数字を選ぶと、それらを昇順に並べる方法はちょうど 1 通りしかありません。つまり、「厳密に増加する n 桁の整数」の個数は、「9 個の数字から n 個を選ぶ組み合わせの総数」と一致します。

したがって、答えは次の式で求められます。

C(9, n) = 9! ÷ (n! × (9 − n)!)

なお、n が 9 より大きい場合は、1〜9 の 9 種類の数字だけでは n 桁の数を作れないため、答えは 0 になります。

アルゴリズムの手順

  • n が 9 以下の場合:組み合わせ 9Cn を計算して返す

  • n が 9 より大きい場合:0 を返す

それでは、実際の実装を見てみましょう。

実装例

from math import factorial as f

class Solution:
    def solve(self, n):
        if n <= 9:
            return f(9) // f(n) // f(9 - n)
        else:
            return 0

ob = Solution()
print(ob.solve(3))

入力

3

出力

84

計算量について

処理の中心は小さな数(最大 9)の階乗計算のみのため、時間計算量・空間計算量ともに実質 O(1) で済みます。n の値にかかわらず常に高速に動作するのがこの手法の大きな利点です。


  1. Pythonで歩行によりk回以上カバーされるブロックの数を数えるプログラム

    2つのリストwalksとtargetが与えられているとします。初期状態では、1次元の数直線上の位置0に立っています。|walks[i]| は歩いたステップ数を表し、walks[i] が正の値なら右方向へ、負の値なら左方向へ移動したことを意味します。歩行中は常に1ブロック(隣接する整数位置)ずつ移動します。ここで求めたいのは、target回以上踏まれたブロック(区間)の総数です。たとえば、入力が walks = [3, -7, 2]、target = 2 の場合、出力は 5 になります。下図のように、[0, 1]、[1, 2]、[2, 3]、[-4, -3]、[-3, -2] の5つの区間がちょ

  2. Pythonで配列の反転数(転倒数)をカウントする方法

    はじめに この記事では、配列内の反転(インバージョン)をカウントする問題とその解決策について詳しく解説します。 問題定義 問題: リストが与えられたとき、その中に含まれる反転の数をカウントして表示します。 反転数とは、配列を昇順にソートされた状態にするために必要な入れ替え(スワップ)の回数を表す指標です。具体的には、i < j かつ arr[i] > arr[j] を満たす要素のペア(i, j)の総数として定義されます。 実装例 # 反転数をカウントする関数 def InvCount(arr, n): inv_count = 0 for i in range(n