1. 引言
在实际开发中,我们经常需要在一个二维矩阵中查找某个单元格的邻居单元格。比如在图像处理、游戏地图算法、网格计算等场景中,这种需求非常常见。本文将介绍如何在二维矩阵中查找指定单元格的所有邻居单元格。
2. 邻居的定义
假设我们有一个 m × n
的矩阵 A
,目标是找出位于第 i
行、第 j
列的单元格 A[i][j]
的所有邻居。邻居的定义通常是:
- 水平方向:左边和右边的单元格
- 垂直方向:上边和下边的单元格
- 对角线方向:四个角上的单元格(共 4 个)
如下图所示,黄色单元格是中心单元格的邻居:
具体来说:
- 垂直邻居:
A[i-1][j]
和A[i+1][j]
- 水平邻居:
A[i][j-1]
和A[i][j+1]
- 对角线邻居:
A[i-1][j-1]
、A[i-1][j+1]
、A[i+1][j-1]
、A[i+1][j+1]
3. 遍历邻居的实现方法
一种常见的做法是通过遍历 (i-1, i, i+1)
和 (j-1, j, j+1)
的所有组合,然后排除掉 (i, j)
自身,并检查是否越界。
✅ 优点:实现简单,适合初学者
❌ 缺点:邻居定义硬编码,不易扩展
以下是 Java 实现示例:
public static List<Integer> findNeighbors(int[][] matrix, int i, int j) {
int m = matrix.length;
int n = matrix[0].length;
List<Integer> neighbors = new ArrayList<>();
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
int x = i + dx;
int y = j + dy;
if (dx == 0 && dy == 0) continue; // 跳过自己
if (x >= 0 && x < m && y >= 0 && y < n) {
neighbors.add(matrix[x][y]);
}
}
}
return neighbors;
}
⚠️ 注意:这里使用的是 0-based 索引,即矩阵索引从 (0,0)
开始。
4. 使用偏移量实现更灵活的邻居查找
为了提高灵活性,可以将邻居的偏移量(offsets)抽象出来,这样只需更改偏移量数组,就可以支持不同的邻居定义。
例如:
// 全部 8 个方向
int[][] allDirections = {
{-1, -1}, {-1, 0}, {-1, 1},
{0, -1}, {0, 1},
{1, -1}, {1, 0}, {1, 1}
};
// 仅上下左右 4 个方向
int[][] crossDirections = {
{-1, 0}, {0, -1}, {0, 1}, {1, 0}
};
传入偏移量数组后,实现如下:
public static List<Integer> findNeighborsWithOffsets(int[][] matrix, int i, int j, int[][] offsets) {
int m = matrix.length;
int n = matrix[0].length;
List<Integer> neighbors = new ArrayList<>();
for (int[] offset : offsets) {
int x = i + offset[0];
int y = j + offset[1];
if (x >= 0 && x < m && y >= 0 && y < n) {
neighbors.add(matrix[x][y]);
}
}
return neighbors;
}
✅ 优点:灵活,可扩展
✅ 缺点:需提前准备好 offset 数组
示例:不同偏移量带来的不同邻居集合
5. 总结
方法 | 是否灵活 | 是否易实现 | 适用场景 |
---|---|---|---|
遍历邻居 | ❌ | ✅ | 快速原型开发 |
使用偏移量 | ✅ | ✅ | 通用算法、可配置场景 |
在实际开发中,推荐使用 偏移量方式,因为它可以轻松应对不同邻居定义(如仅上下左右、仅对角线、曼哈顿距离等),并提升代码的可维护性与可测试性。