アルゴリズム概要

問題の説明

整数 n が与えられたとき、 1 から n までの連続整数をすべて使って構成できる「構造的に異なる二分探索木(BST)」の個数を返す問題です。

入出力例

Example 1:

Input: n = 3
Output: 5

解説: n=3 のとき、構造的に異なるBSTは5通り存在します。

Example 2:

Input: n = 1
Output: 1

制約条件

戦略

主要ポイント

ステップバイステップ解説

Python実装

class Solution:
    """
    Unique Binary Search Trees 問題を解くクラス。

    カタラン数の漸化式を用いてO(n)/O(1)で計算。
    """

    def numTrees(self, n: int) -> int:
        """
        LeetCode用エントリポイント(競技プログラミング向け実装)。

        Args:
            n: ノード数 (1 <= n <= 19)

        Returns:
            構造的に異なるBSTの個数

        Complexity:
            Time: O(n)
            Space: O(1)
        """
        # カタラン数の漸化式: C_0 = 1
        c: int = 1

        # C_n = C_{n-1} * 2(2n - 1) / (n + 1)
        for i in range(1, n + 1):
            # 整数除算で誤差なく計算
            c = c * 2 * (2 * i - 1) // (i + 1)

        return c

フローチャート

開始 numTrees(n) 初期化 c = 1 (C₀の値) ループ開始 i = 1 から n まで i <= n ? 漸化式を適用 c = c × 2(2i - 1) ÷ (i + 1) はい i = i + 1 次の i へ 終了 return c いいえ

フローの説明:
1. 初期化: c = 1 で開始(C₀の値)
2. ループ開始: i = 1 から n まで反復
3. 条件分岐: i <= n であれば処理を続行、そうでなければ終了
4. 漸化式適用: c = c × 2(2i - 1) ÷ (i + 1) を計算
5. インクリメント: i を1増やす
6. ループバック: 条件分岐に戻る(紫の矢印)
7. 終了: ループ完了後、c を返す

計算量分析

項目 計算量 備考
時間 O(n) ループが n 回実行され、各ステップは定数時間
空間 O(1) 変数 c, i のみ使用(配列不要)

他手法との比較

アプローチ 時間 空間 備考
漸化式(本実装) O(n) O(1) 最もシンプルで高速
DP配列 O(n²) O(n) 定義に忠実だが遅い
再帰+メモ化 O(n²) O(n) 関数呼び出しオーバーヘッド