螺旋矩阵
矩阵 模拟题目描述
给定一个 m × n 的矩阵,按照顺时针螺旋顺序,返回矩阵中的所有元素。
思路分析
螺旋遍历的本质是一圈一圈地向内收缩。每走完一圈,当前圈的四条边就被"消耗掉",矩阵的有效区域随之缩小。用四个变量 top、bottom、left、right 来描述这个不断收缩的边界,就能清晰地表达这一过程。
每一轮迭代分为四个阶段:先沿着 top 行从左到右收集元素,收集完毕后将 top 下移一行;再沿着 right 列从上到下收集,完成后将 right 左移一列;接着沿着 bottom 行从右到左收集,完成后将 bottom 上移一行;最后沿着 left 列从下到上收集,完成后将 left 右移一列。
需要注意的是,后两个阶段在执行之前必须检查边界是否仍然有效。收集底部行之前,要确认 top <= bottom,即顶部边界还没有越过底部边界,否则这一行已经被之前的遍历覆盖了;同理,收集左列之前,要确认 left <= right,确保还有列没有被处理过。遗漏这两个守卫条件,在遍历非方形矩阵或只剩单行、单列时就会重复采集元素。
只要 left <= right 且 top <= bottom 同时成立,就说明矩阵内还有未访问的元素,循环继续;任意一个条件不满足时,遍历结束。
算法步骤
- 若矩阵为空,直接返回空数组。
- 初始化四个边界:
top = 0、bottom = m - 1、left = 0、right = n - 1。 - 进入循环,条件为
left <= right && top <= bottom:- 从左到右遍历
top行,收集元素,然后top++。 - 从上到下遍历
right列,收集元素,然后right--。 - 若
top <= bottom,从右到左遍历bottom行,收集元素,然后bottom--。 - 若
left <= right,从下到上遍历left列,收集元素,然后left++。
- 从左到右遍历
- 返回结果数组。
示例代码
复杂度分析
- 时间复杂度:
O(m × n),矩阵中每个元素恰好被访问一次。 - 空间复杂度:
O(1),不计返回数组,只使用了四个边界变量。
示例演示
以如下 3 × 4 矩阵为例:
第一轮:
收缩后边界变为:top=1, bottom=1, left=1, right=2
第二轮:
最终结果:[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]