
本文详解 java 中螺旋矩阵生成的常见边界越界问题,重点分析奇数阶矩阵下原逻辑崩溃的根本原因,并提供健壮、易理解的双指针迭代解法及关键边界修正策略。
本文详解 java 中螺旋矩阵生成的常见边界越界问题,重点分析奇数阶矩阵下原逻辑崩溃的根本原因,并提供健壮、易理解的双指针迭代解法及关键边界修正策略。
在实现螺旋矩阵(Spiral Matrix)生成时,一个经典且易被忽视的陷阱是:当矩阵边长为奇数时,传统四边遍历循环极易因边界条件未闭合而触发 ArrayIndexOutOfBoundsException。你提供的代码在 n = 4(偶数)时正常运行,但在 n = 5(奇数)时崩溃——这并非偶然,而是源于内层循环对“单行/单列中心单元格”的重复访问或遗漏处理。
? 根本问题定位
观察原始代码的关键循环结构:
// 1. 顶行:leftCol → rightCol-1(不包含 rightCol)
for(int i = leftCol; i < rightCol; i++) { ... }
// 2. 右列:topRow → bottomRow-1(不包含 bottomRow)
for(int j = topRow; j < bottomRow; j++) { ... }
// 3. 底行:rightCol → leftCol+1(递减,不包含 leftCol)
for(int i = rightCol; i > leftCol; i--) { ... }
// 4. 左列:bottomRow → topRow+1(递减,不包含 topRow)
for(int j = bottomRow; j > topRow; j--) { ... }问题在于:当 topRow == bottomRow 且 leftCol == rightCol(即只剩一个中心元素)时,上述四个 for 循环均因边界条件( 或 <code>>)全部跳过,导致中心位置 mat[topRow][leftCol] 永远未被赋值,而 num 却持续递增,最终在下一轮循环中因 topRow > bottomRow 或 leftCol > rightCol 导致索引越界(例如 mat[2][3] 访问已收缩出界的区域)。
更严重的是,原始逻辑未在每次方向遍历后检查是否已填满全部 n² 个元素,从而放任无效循环继续执行。
✅ 正确解法:安全边界 + 提前终止
推荐采用 双指针收缩 + 显式终止条件 的稳健模式。核心思想是:每轮填充一行/一列后,立即更新边界;每次填充前,先校验当前边界是否仍有效(top )。
以下是修复后的标准实现:
public class SpiralMatrix {
public static void main(String[] args) {
int n = 5;
int[][] matrix = generateSpiralMatrix(n);
printMatrix(matrix);
}
public static int[][] generateSpiralMatrix(int n) {
int[][] mat = new int[n][n];
int num = 1;
int top = 0, bottom = n - 1;
int left = 0, right = n - 1;
while (num <= n * n) {
// ➡️ 从左到右填充顶行
if (top <= bottom) {
for (int i = left; i <= right; i++) {
mat[top][i] = num++;
}
top++; // 顶行已填完,下移边界
}
// ⬇️ 从上到下填充右列
if (left <= right) {
for (int i = top; i <= bottom; i++) {
mat[i][right] = num++;
}
right--; // 右列已填完,左移边界
}
// ⬅️ 从右到左填充底行
if (top <= bottom) {
for (int i = right; i >= left; i--) {
mat[bottom][i] = num++;
}
bottom--; // 底行已填完,上移边界
}
// ⬆️ 从下到上填充左列
if (left <= right) {
for (int i = bottom; i >= top; i--) {
mat[i][left] = num++;
}
left++; // 左列已填完,右移边界
}
}
return mat;
}
public static void printMatrix(int[][] mat) {
for (int[] row : mat) {
for (int val : row) {
System.out.printf("%3d ", val);
}
System.out.println();
}
}
}✅ 关键修复点总结
| 问题点 | 原始逻辑缺陷 | 修复方案 |
|---|---|---|
| 边界未校验 | 循环前无 if (top 等判断
|
每次方向填充前添加边界有效性检查 |
| 循环范围错误 | 使用 / <code>> 导致中心遗漏
|
统一使用 / <code>>=,确保单行/单列可完整填充
|
| 终止时机模糊 | 依赖 num ,但越界发生在循环体内
|
边界校验 + num 双重保障
|
| 变量名易混淆 |
bottonRow 拼写错误、语义不清 |
使用 top/bottom/left/right,语义明确、不易出错 |
? 提示:该解法时间复杂度为 O(n²),空间复杂度 O(1)(不计输出矩阵),适用于任意正整数
n,包括n = 1的边界情况(输出[[1]])。
通过严格约束每一步操作的可行域,并将“填充动作”与“边界收缩”解耦校验,即可彻底规避奇偶维度差异带来的越界风险,写出真正鲁棒的螺旋矩阵生成器。

















