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(スケッチ) • 中級⏱️ 19 分で読める

行列とグリッド問題

グリッドとしての 2D 配列

マトリックスは単なる 2D 配列ですが、インタビューでは、地図、ボード、迷路などの グリッド を表すことがよくあります。各セル grid[r][c] はノードであり、その隣のセルは隣接セルです。

grid = [
  [1, 1, 0],
  [1, 0, 0],
  [0, 0, 1]
]

行r、列c、寸法m × n。シンプルですが、その上に構築されたパターンは強力です。

方向性配列

4 つの個別の if ステートメントを記述する代わりに、方向配列 を使用します。

# 4-directional (up, down, left, right)
dirs = [(-1,0), (1,0), (0,-1), (0,1)]

# 8-directional (includes diagonals)
dirs = [(-1,0),(1,0),(0,-1),(0,1),
        (-1,-1),(-1,1),(1,-1),(1,1)]

for dr, dc in dirs:
    nr, nc = r + dr, c + dc
    if 0 <= nr < m and 0 <= nc < n:
        # process neighbour

これは、グリッド問題の中で最も再利用可能なスニペットです。

🤯
方向配列のトリックは「デルタ エンコーディング」と呼ばれることもあります。これは、ゲーム開発、画像処理、競技プログラミングなど、グリッドが使用されるあらゆる場面で使用されます。

グリッド上の BFS - 迷路の最短経路

BFS は、重み付けされていないグリッドで 最短パス を見つけます。ソースから開始して、距離 1 にあるすべての近傍を探索し、次に距離 2 というように探索します。

from collections import deque

def shortest_path(grid, start, end):
    m, n = len(grid), len(grid[0])
    q = deque([(start[0], start[1], 0)])
    visited = {(start[0], start[1])}
    dirs = [(-1,0),(1,0),(0,-1),(0,1)]
    while q:
        r, c, dist = q.popleft()
        if (r, c) == end:
            return dist
        for dr, dc in dirs:
            nr, nc = r+dr, c+dc
            if 0<=nr<m and 0<=nc<n and (nr,nc) not in visited and grid[nr][nc]==0:
                visited.add((nr, nc))
                q.append((nr, nc, dist+1))
    return -1
BFS は格子状の迷路全体にレベルごとに拡張します
BFS はセルをレベルごとに探索し、最短パスを保証します。

グリッド上の DFS - 塗りつぶしと島の数

塗りつぶし (ペイント バケツ ツールと同様): 開始セルから、同じ色の接続されているすべてのセルを変更します。 DFS または BFS は両方とも機能します。

島の数: グリッドをスキャンします。 1 を見つけたら、DFS/BFS を実行して島全体を訪問済みとしてマークし、カウントを増やします。

def num_islands(grid):
    count = 0
    for r in range(len(grid)):
        for c in range(len(grid[0])):
            if grid[r][c] == '1':
                dfs(grid, r, c)  # mark island
                count += 1
    return count
レッスン 10 / 100%完了
←貪欲アルゴリズム

ディスカッション

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

🧠クイックチェック

「島の数」で、DFS 中にセルを訪問済みとしてマークするのはなぜですか?

腐ったオレンジ - マルチソース BFS

最初に腐ったオレンジはすべてソースになります。それらをすべて時間 0 でキューにプッシュし、次に BFS にプッシュします。各レベルは 1 分です。列が空になったら、新鮮なオレンジが残っているかどうかを確認します。

Minute 0:  [2, 1, 1]    2 = rotten, 1 = fresh
           [1, 1, 0]
           [0, 1, 1]

Minute 4:  [2, 2, 2]    All reachable oranges rotten
           [2, 2, 0]
           [0, 2, 2]

重要な洞察: マルチソース BFS は、1 つのノードではなく複数のノードから同時に開始されます。

🧠クイックチェック

「Rotting Oranges」と標準の BFS の違いは何ですか?

スパイラル行列トラバーサル

右→下→左→上という螺旋の順序でマトリックスを歩き、パスごとに境界を縮小します。

def spiral(matrix):
    res = []
    top, bot = 0, len(matrix) - 1
    left, right = 0, len(matrix[0]) - 1
    while top <= bot and left <= right:
        for c in range(left, right + 1):
            res.append(matrix[top][c])
        top += 1
        for r in range(top, bot + 1):
            res.append(matrix[r][right])
        right -= 1
        if top <= bot:
            for c in range(right, left - 1, -1):
                res.append(matrix[bot][c])
            bot -= 1
        if left <= right:
            for r in range(bot, top - 1, -1):
                res.append(matrix[r][left])
            left += 1
    return res

マトリックスの回転 (90°)

N×N 行列をその場で時計回りに回転します。転置 ([r][c] を [c][r] と交換)、各行を反転します。

Original → Transpose → Reverse rows
1 2 3     1 4 7       7 4 1
4 5 6  →  2 5 8   →   8 5 2
7 8 9     3 6 9       9 6 3
🤔
Think about it:反時計回りに回転するには、最初に行を反転してから転置しますか、それとも転置してから列を反転しますか?紙に書いてみてください。

ソートされた 2D マトリックスでの検索

2 つの一般的なバリエーション:

  • 行と列は個別にソート - 右上隅から開始します。ターゲットが小さい場合は左に移動します。大きい場合は下に移動します。 O(m + n)。
  • 完全にソート (各行は前の行の終了位置から始まります) - フラットにソートされた配列および二分検索として処理されます。 O(log(m × n))。

グリッド上の動的プログラミング

一意のパス: 左上から右下まで、右または下にのみ移動するパスをカウントします。 dp[r][c] = dp[r-1][c] + dp[r][c-1]。

最小パス合計: 同じ考え方ですが、最小の受信パスを選択します。

これらは、多くの場合、2D 動的プログラミングへの最も穏やかな入門書となります。

🧠クイックチェック

Unique Paths 問題では、任意の列 c の dp[0][c] は何ですか?

グリッド パターンのチートシート

|パターン |テクニック |重要な問題 | |----------|-----------|---------------| |最短パス (重み付けなし) | BFS |迷路の最短経路 | |接続されたコンポーネント | DFS / BFS |島の数 | |マルチソースの広がり |マルチソース BFS |腐ったオレンジ |走査順序 |境界ポインタ |スパイラルマトリックス | |インプレース変換 |トランスポーズ + リバース |画像を回転 | |パスを数える | DP |ユニークなパス | |並べ替えられたグリッドで検索 |階段/二分探索 | 2D マトリックスを検索 |

🤔
Think about it:多くのグリッド問題は、実際には偽装されたグラフ問題です。グリッド上で BFS よりも DFS を好むのはどのような場合ですか?

📚 続きを読む

  • NeetCode - 2D 動的プログラミング - 視覚的な説明付きのグリッド DP 問題
  • 技術面接ハンドブック - マトリックス - 一般的なパターンとテクニック
  • LeetCode Matrix タグ] - 数百の練習問題