
本文详解 leetcode 885 题“spiral matrix iii”的常见超时(tle)根源,指出原代码因边界变量双步更新和循环终止条件错误导致无限循环,并提供时间复杂度更优、逻辑清晰、无状态残留的迭代实现。
本文详解 leetcode 885 题“spiral matrix iii”的常见超时(tle)根源,指出原代码因边界变量双步更新和循环终止条件错误导致无限循环,并提供时间复杂度更优、逻辑清晰、无状态残留的迭代实现。
LeetCode 第 885 题要求从给定起点 (rStart, cStart) 出发,按顺时针螺旋顺序遍历无限二维网格,仅记录落在 [0, rows) × [0, cols) 范围内的前 rows × cols 个有效坐标。看似简单,但极易因边界控制失当引发无限循环或大量无效遍历,最终触发 TLE。
原代码的核心问题有三:
- 变量误更新:rStart, cStart, rEnd, cEnd 在每轮循环中被 ±2 修改(如 cStart = cStart - 2),意图补偿“拐角”,但实际破坏了螺旋步长的单调递增规律,导致路径偏移(例如跳过 (1,3)),使算法永远无法覆盖全部目标格子;
- 循环条件宽松:内层 for 使用 =,未提前截断“拐角单元格”,造成重复/越界判断开销,且需在循环体内反复检查 count
- 状态污染风险:count 作为类成员变量未重置,若测试平台复用实例,将导致后续用例直接失败。
✅ 正确解法应遵循「单步扩张 + 边界裁剪 + 即时退出」原则:
- 每轮螺旋的四条边分别对应:→(东)、↓(南)、←(西)、↑(北);
- 每次移动仅扩展 1 单位边界(如 cEnd++),保证步长序列严格为 1,1,2,2,3,3,...;
- 内层循环统一使用左闭右开区间(如 for (int c = cStart; c
- 坐标有效性检查前置:仅当当前行/列区间与矩阵有交集时才执行循环,大幅减少空转(例如 if (rStart >= 0) { for (...) ... });
- count 改为局部变量,addToAns 接收 int[] 单元而非整个数组,职责单一、无副作用。
以下是优化后的完整实现(时间复杂度 O(rows × cols),空间复杂度 O(1) 额外空间):
class Solution {
public int[][] spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
int size = rows * cols;
int[][] ans = new int[size][2];
int rEnd = rStart + 1;
int cEnd = cStart + 1;
int count = 0;
while (true) {
// → East: row = rStart, col ∈ [cStart, cEnd)
if (rStart >= 0 && rStart = 0) cStart--; // shrink left bound only if still in range
// ↓ South: col = cEnd, row ∈ [rStart, rEnd)
if (cEnd >= 0 && cEnd = 0) rStart--; // shrink top bound
// ← West: row = rEnd, col ∈ (cStart, cEnd]
if (rEnd >= 0 && rEnd cLow && count = 0 && cStart rLow && count <p>? <strong>关键优化点总结</strong>:</p>
- ✅ 无条件重置:count 始终为局部变量,杜绝跨用例污染;
- ✅ 边界预裁剪:Math.max/min 确保循环范围严格落在 [0, rows) 和 [0, cols) 内,消除 90% 以上无效 if 判断;
- ✅ 即时退出:每个方向遍历后检查 count == size,避免冗余循环;
- ✅ 步长精准:四边扩张严格遵循 1,1,2,2,3,3... 规律,由 cStart--, rStart--, cEnd++, rEnd++ 单步实现,路径完全可验证。
该实现通过逻辑分层与防御式编程,在保证正确性的同时将时间复杂度稳定在理论下限 O(rows × cols),彻底规避 TLE 风险。










