螺旋矩阵总结
1.leetcode 59
2.leetcode 54
这两道题的核心区别如下:
| 对比项 | LeetCode 54 螺旋矩阵 | LeetCode 59 螺旋矩阵 II |
|---|---|---|
| 输入 | 给你一个现成矩阵 | 只给一个数字 n |
| 输出 | 按螺旋顺序返回一维数组 | 生成 n×n 螺旋矩阵并返回 |
| 方向顺序 | 右→下→左→上 | 完全一样:右→下→左→上 |
| 遍历方式 | 读取元素(不修改原矩阵) | 填充数字(修改矩阵) |
| 边界判断 | 必须每一步判断,防止越界 | 因为是 n×n 正方形,更简单 |
| 结束条件 | 上下 / 左右边界交叉即停 | 填完 1~n² 自动结束 |
| 是否会剩单行 / 列 | 一定会(任意矩形) | 不会(正方形,刚好填满) |
| 难度 | 稍难(处理矩形、越界) | 更简单(标准正方形圈) |
代码里的易错点总结:
1. 59 题(生成正方形)易错点 - **变量重复定义**: 你在第10行定义了 `int i,j;`,又在循环内 `int i = startx; int j = starty;`,虽然语法允许,但容易混淆作用域。
✅ 建议:要么只在循环内定义,要么外层定义后循环内直接赋值。
- **中间元素赋值**: 你注释里特别提到:`不能用i,j,因为出了while循环,ij已经自减到0了`,这是非常关键的易错点! ✅ 必须用 `mid = n/2` 单独赋值,不能依赖循环里的 `i/j`。
- **offset 边界逻辑**: `j < n - offset` 这种写法是「左闭右开」,如果写成 `<=` 会重复赋值/越界。 ✅ 必须严格遵守「末位不遍历」的规则,否则会和下一条边重复。 -
**圈数计算**: `loop = n/2` 只适用于正方形,长方形会多算/少算,**绝对不能**套用到54题。
2. 54 题(读取长方形)易错点 -
**边界判断遗漏**: 你之前的代码如果不加 `if(top>bottom) break` 这类判断,会直接报内存越界(就是你遇到的 `0xbebebebe` 错误)。
✅ 每条边走完必须收缩边界并判断是否还有剩余元素。
- **空矩阵访问**: 你现在的代码没加空矩阵判断,如果输入 `[]` 或 `[[]]`,访问 `matrix[0].size()` 会崩溃。 ✅ 开头必须加 `if(matrix.empty() || matrix[0].size()) return res;`。
- **for 循环初始化警告**: 你之前写 `for(j;j<...;j++)` 会触发 `expression result unused` 警告。 ✅ 正确写法是 `for(;j<...;j++)` 或重新定义循环变量(如 `for(int col=left;...;col++)`)。
- **方向顺序**: 必须严格按「右→下→左→上」,一旦顺序错,结果就完全乱掉。
三、两种写法的本质区别
1. **59 是「主动生成」**: - 已知最终形状是正方形,所以可以提前算圈数、用 `offset` 控制每圈范围。 - 逻辑更简单,不会出现「走一半就没了」的情况。
2. **54 是「被动读取」**: - 输入形状未知(可能是长条、扁条),必须用动态边界实时判断。 - 核心是「**走一步看一步**」,每一步都要确认还有没有元素可走。
