AIUnlimited
🌳

AI基础

🌱
AI 种子

从零开始

🌿
AI 萌芽

打好基础

🌳
AI 枝干

付诸实践

🏕️
AI 树冠

深入探索

🌲
AI 森林

精通AI

🔨

AI精通

✏️
AI 草图

从零开始

🪨
AI 雕刻

打好基础

⚒️
AI 匠心

付诸实践

💎
AI 打磨

深入探索

🏆
AI 杰作

精通AI

📘

AI实战

📖
理解开源模型

开源模型的基础知识和资源

🎯
问题到模型任务

将业务问题转化为模型任务

⚡
跑通第一个模型

30分钟快速看到第一个结果

🔧
微调与评测

微调模型并评估性能

🚀
应用系统

构建实际AI应用系统

🎨
生成式AI

探索AIGC的开源模型

🤖
Agent智能体

学习Agent框架和MCP工具

📐
基础补充

LLM基础知识和评测

🎓

Claude 学院

🤖
Claude 101 入门

用 Claude 学习 AI 基础知识

💻
Claude Code 101 入门

让 Claude 成为你的结对编程伙伴

🤝
Claude Cowork 入门

与 Claude 协作完成复杂项目

⚙️
Claude 平台 101

使用 Claude API 构建应用

实验室

已加载 7 个实验
🧬神经网络沙盒🤖AI 还是人类?🥋提示工程道场🏁算法竞速🧠AI 知识挑战🏗️系统设计画布
🎯模拟面试进入实验室→
🚀

职业发展

🚀
面试发射台

开启你的旅程

🌟
行为面试精通

掌握软技能

💻
技术面试

通过编程轮次

🤖
AI与ML面试

ML面试精通

🏆
Offer与未来

拿下最好的Offer

立即开始
AIUnlimited

AI 教育平台

沪ICP备18025655号-11

学习

  • AI基础
  • AI实战
  • Claude学院
  • 实验室
  • 职业发展

社区

  • 关于
  • 常见问题

支持

  • 服务条款
  • 隐私政策
  • 联系我们
AI & 工程学习计划›✏️ AI 草图›课程›矩阵与网格问题
🗺️
AI 草图 • 中级⏱️ 19 分钟阅读

矩阵与网格问题

二维数组作为网格

矩阵只是一个二维数组,但在面试中它通常代表一个网格 - 地图、棋盘或迷宫。每个单元格grid[r][c]是一个节点,它的邻居是相邻单元格。

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

行r,列c,尺寸m × n。简单 - 但构建在其之上的模式非常强大。

定向数组

不要编写四个单独的 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
🧠小测验

在”岛屿数量”中,为什么我们将单元格标记为 DFS 期间访问过的单元格?

第 10 课,共 10 课已完成 0%
←贪心算法

讨论

登录 参与讨论

Rotting Oranges - 多源 BFS

所有最初腐烂的橙子都是来源。在时间0将它们全部推入队列,然后进行BFS。每个级别一分钟。当队列清空时,检查是否还有新鲜的橙子。

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 同时从多个节点启动,而不是从一个节点启动。

🧠小测验

”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:

要逆时针旋转,是先反转行然后转置,还是转置然后反转列?在纸上尝试一下。

在排序的二维矩阵中搜索

两种常见的变体:

  • 行和列独立排序 - 从右上角开始。如果目标较小,则向左移动;如果较大,则向下移动。 O(m+n)。
  • 完全排序(每行从前一行结束的位置开始)- 视为平面排序数组和二分搜索。 O(log(m × n))。

网格动态规划

**唯一路径:**计算从左上角到右下角仅向右或向下移动的路径。 dp[r][c] = dp[r-1][c] + dp[r][c-1]。

**最小路径总和:**相同的想法,但选择最小传入路径。

这些通常是对 2D 动态规划最温和的介绍。

🧠小测验

在唯一路径问题中,任意列 c 的 dp[0][c] 是多少?

网格图案备忘单

|图案|技术|关键问题| |--------|------------|-------------| |最短路径(未加权)| BFS |迷宫最短路径| |连接组件| DFS / BFS |岛屿数量 | |多源传播|多源BFS |腐烂的橙子| |遍历顺序 |边界指针|螺旋矩阵| |就地变换 |转置 + 反转 |旋转图像 | |计算路径 | DP |独特的路径| |在排序网格中搜索 |楼梯/二分查找 |搜索二维矩阵 |

🤔
Think about it:

许多网格问题实际上是变相的图形问题。在网格上什么时候你更喜欢 DFS 而不是 BFS,反之亦然?


📚 进一步阅读

  • 【NeetCode - 2D动态规划](https://neetcode.io/roadmap) - 网格DP问题可视化解释
  • 技术面试手册 - Matrix - 常见模式和技巧
  • LeetCode Matrix标签 - 数百道练习题