AIUnlimited
🌳

AI基礎

🌱
AI Seeds(種)

ゼロから始める

🌿
AI Sprouts(芽)

基礎を築く

🌳
AI Branches(枝)

実践に活かす

🏕️
AI Canopy(樹冠)

深く学ぶ

🌲
AI Forest(森)

AIをマスターする

🔨

AIマスタリー

✏️
AI Sketch(スケッチ)

ゼロから始める

🪨
AI Chisel(鑿)

基礎を築く

⚒️
AI Craft(制作)

実践に活かす

💎
AI Polish(磨き上げ)

深く学ぶ

🏆
AI Masterpiece(傑作)

AIをマスターする

📘

AI実践

📖
オープンソースモデルを理解する

オープンソースモデルの基礎とリソース

🎯
問題からモデルタスクへ

ビジネス問題をモデルタスクに変換

⚡
最初のモデルを実行する

30分で最初の結果を見る

🔧
ファインチューニングと評価

モデルをファインチューニングし、パフォーマンスを評価

🚀
アプリケーションシステム

実際のAIアプリケーションを構築

🎨
生成AI

オープンソースAIGCモデルを探索

🤖
エージェント

エージェントフレームワークとMCPツールを学ぶ

📐
補足基礎

LLMの基礎と評価

🎓

Claude アカデミー

🤖
Claude 101

Learn AI basics with Claude

💻
Claude Code 101

Code with Claude as your pair programmer

🤝
Introduction to Claude Cowork

Collaborate with Claude on complex projects

⚙️
Claude Platform 101

Build apps with the Claude API

ラボ

7つの実験がロード済み
🧬ニューラルネットワークサンドボックス🤖AI か人間か?🥋プロンプトエンジニアリング道場🏁アルゴリズムレース🧠AIトリビアチャレンジ🏗️システム設計キャンバス
🎯模擬面接ラボへ入る→
🚀

キャリア発展

🚀
面接ローンチパッド

旅を始めよう

🌟
行動面接マスター

ソフトスキルをマスター

💻
技術面接

コーディング面接を突破

🤖
AI・ML面接

ML面接をマスター

🏆
オファーとその先

最高のオファーを獲得

始める
AIUnlimited

MITライセンス

沪ICP备18025655号-11

学ぶ

  • AI基礎
  • AI実践
  • Claude アカデミー
  • ラボ
  • キャリア発展

コミュニティ

  • 概要
  • よくある質問

サポート

  • footer.terms
  • footer.privacy
  • footer.contact
AI & エンジニアリング アカデミックス›✏️ AI Sketch(スケッチ)›レッスン›再帰とバックトラッキング
🧩
AI Sketch(スケッチ) • 中級⏱️ 20 分で読める

再帰とバックトラッキング

再帰の基礎

再帰関数は、チェーンを停止する 基本ケースに達するまで、問題の小さいバージョンで自分自身を呼び出します。

すべての再帰には次の 2 つのことが必要です。

  1. 基本ケース - 直接返す最も単純な入力。
  2. 再帰的なケース - 問題を細分化し、自分自身に電話をかけます。
def factorial(n):
    if n <= 1:        # base case
        return 1
    return n * factorial(n - 1)  # recursive case

コールスタック - 視覚化

各再帰呼び出しは、フレームを呼び出しスタックにプッシュします。基本ケースに戻ると、フレームは逆の順序でポップされます。

factorial(4)
  → factorial(3)
    → factorial(2)
      → factorial(1) → returns 1
    ← returns 2
  ← returns 6
← returns 24

基本ケースがない場合、スタックはオーバーフローします。 Python のデフォルトの再帰制限は 1,000 フレームです。

🤯
Python のデフォルトの再帰制限 1,000 は、意図的に控えめに設定されています。 sys.setrecursionlimit() を使用して値を上げることができますが、深い再帰には通常、反復ソリューションが推奨されます。

フィボナッチ - 古典的なトラップ

単純な再帰フィボナッチは、同じ部分問題を再計算するため、O(2ⁿ) です。メモ化はこれを O(n) 時間と空間で修正します。

from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)
繰り返しの下位問題を示すフィボナッチの再帰木
メモ化を行わない場合、 fib(5) は 15 回の呼び出しを行います。これで、たったの5。

バックトラッキング - すべて試してから元に戻す

バックトラッキングは、ひねりを加えた再帰です。選択を行い、再帰し、次のオプションを試す前に選択を元に戻します。迷路を探索するようなものだと考えてください。前に歩いて、行き止まりに突き当たり、戻って、次の道を試してください。

バックトラッキングテンプレート

def backtrack(state, choices):
    if is_solution(state):
        result.append(state.copy())
        return
    for choice in choices:
        if is_valid(choice):
            state.add(choice)       # choose
            backtrack(state, ...)   # explore
            state.remove(choice)    # un-choose

この 3 ステップのパターン (選択、探索、選択を解除) は、ほぼすべてのバックトラッキング問題の根幹です。

🧠クイックチェック

バックトラッキング テンプレートで、再帰呼び出しの後に選択を取り消すのはなぜですか?

順列

[1, 2, 3] のすべての順序を生成します。各レベルで、未使用の番号を選択し、再帰的に選択し、選択を解除します。

         []
      /   |   \
    [1]  [2]  [3]
    / \   ...
 [1,2] [1,3]
   |      |
[1,2,3] [1,3,2]  ... (6 total)
レッスン 8 / 100%完了
←二分探索パターン

ディスカッション

ログイン ディスカッションに参加

n! 個の順列があるため、時間計算量は O(n × n!) になります。

組み合わせとサブセット

組み合わせ (n は k を選択): 各要素で、それを含めるかスキップしますが、重複を避けるために前方へのみ再帰します。

サブセット: サイズ制約のない同じ考え方 - 再帰ツリー内のすべてのノードは有効なサブセットです。 2ⁿ のサブセットがあります。

🤔
Think about it:順列は n を生成します!サブセットは 2ⁿ を生成します。 n=10 の場合、3,628,800 対 1,024 となり、大きな違いがあります。なぜ?

N-クイーンズ - ウォークスルー

N×NのボードにN個のクイーンを配置し、お互いに攻撃しないようにします。 N=4の場合:

. Q . .
. . . Q
Q . . .
. . Q .

戦略: 1 列に 1 つのクイーンを配置します。各行について、すべての列を試してください。列、主対角線、対対角線の競合を確認します。安全であれば、配置して次の行に再帰します。行き詰まったら後戻りしてください。

cols、diag (行 − 列)、および anti_diag (行 + 列) の 3 つのセットとの競合を追跡します。

🧠クイックチェック

N-Queens 問題では、対角線の競合を効率的にチェックするにはどうすればよいでしょうか?

数独ソルバー - コンセプト

空のセルを見つけて、1 ~ 9 の数字を試します。各桁について、行、列、および 3×3 ボックスの制約を確認します。有効な場合は、配置して再帰します。どの数字も機能しない場合は、元に戻して元に戻します。制約を取り除くことで、巨大な検索スペースにもかかわらず扱いやすくなります。

グリッド内の単語検索

文字の 2D ボードとターゲット単語が与えられた場合、すべてのセルから開始して 4 方向に DFS を実行し、一度に 1 文字ずつ照合します。再帰中にセルを訪問済みとしてマークし、バックトラックのマークを解除して他のパスを許可します。

バックトラッキングの時間計算量

コストは、分岐係数 (ステップごとの選択肢) と 深さ (解決までのステップ) によって異なります。 b 個の分岐と d 個の深さの場合: O(bᵈ)。

|問題 |分岐 |深さ |複雑さ | |-----------|-----------|-------|-----------| |順列 | n、n−1、… | n |お(ん!) | |サブセット | 2 | n | O(2ⁿ) | | N-クイーンズ | ~n | n | O(n!) 最悪の場合 |

最適化のための枝刈り

剪定とは、失敗するとわかっている枝をスキップすることを意味します。例:

  • N-Queens: すでに占有されている列をスキップします。
  • 数独: 制約に違反する数字をスキップします。
  • 組み合わせ合計: 残りの合計が 0 未満の場合はスキップします。

適切な枝刈りを行うと、非現実的な検索を迅速な検索に変えることができます。

🧠クイックチェック

バックトラッキング アルゴリズムで枝刈りは何を行うのでしょうか?

🤔
Think about it:多くのバックトラッキング問題は動的計画法でも解決できます。両者のアプローチにおける主な違いは何ですか?

📚 続きを読む

  • NeetCode - バックトラック プレイリスト - ビデオ ウォークスルーで厳選された問題
  • 技術面接ハンドブック - 再帰 - パターンと一般的な落とし穴
  • LeetCode バックトラッキング学習計画 - 進歩的な問題集セット