LeetCode 54. 螺旋矩阵

题目描述

54. 螺旋矩阵

题目

给定一个 mn 列的矩阵 matrix,请按顺时针螺旋顺序返回矩阵中的所有元素。

示例 1

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

image-20230304214740996

image-20230304214747567

思路分析

解法一:边界模拟(推荐)

核心思路

维护四个边界 topbottomleftright,按顺时针方向逐层收缩:

  1. 向右遍历 top 行(left → right),然后 top++
  2. 向下遍历 right 列(top → bottom),然后 right--
  3. 向左遍历 bottom 行(right → left),然后 bottom--(需判断 top <= bottom
  4. 向上遍历 left 列(bottom → top),然后 left++(需判断 left <= right

步骤 3、4 需要额外判断,防止单行或单列时重复遍历。


复杂度分析

  • 时间复杂度:O(m × n),其中 m、n 分别表示矩阵的行数和列数。
  • 空间复杂度:O(1),仅使用常数个边界变量。
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        if (matrix == null || matrix.length == 0) {
            return res;
        }
        int m = matrix.length, n = matrix[0].length;
        int top = 0, bottom = m - 1, left = 0, right = n - 1;

        while (top <= bottom && left <= right) {
            // 从左到右遍历 top 行
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
            }
            top++;

            // 从上到下遍历 right 列
            for (int i = top; i <= bottom; i++) {
                res.add(matrix[i][right]);
            }
            right--;

            // 判断是否还有行可遍历(防止单行重复)
            if (top <= bottom) {
                // 从右到左遍历 bottom 行
                for (int i = right; i >= left; i--) {
                    res.add(matrix[bottom][i]);
                }
                bottom--;
            }

            // 判断是否还有列可遍历(防止单列重复)
            if (left <= right) {
                // 从下到上遍历 left 列
                for (int i = bottom; i >= top; i--) {
                    res.add(matrix[i][left]);
                }
                left++;
            }
        }
        return res;
    }
}
func spiralOrder(matrix [][]int) []int {
	if len(matrix) == 0 || len(matrix[0]) == 0 {
		return nil
	}

	m, n := len(matrix), len(matrix[0])
	res := make([]int, 0, m*n)
	top, bottom, left, right := 0, m-1, 0, n-1

	for top <= bottom && left <= right {
		// 从左到右遍历 top 行
		for i := left; i <= right; i++ {
			res = append(res, matrix[top][i])
		}
		top++

		// 从上到下遍历 right 列
		for i := top; i <= bottom; i++ {
			res = append(res, matrix[i][right])
		}
		right--

		// 判断是否还有行可遍历
		if top <= bottom {
			// 从右到左遍历 bottom 行
			for i := right; i >= left; i-- {
				res = append(res, matrix[bottom][i])
			}
			bottom--
		}

		// 判断是否还有列可遍历
		if left <= right {
			// 从下到上遍历 left 列
			for i := bottom; i >= top; i-- {
				res = append(res, matrix[i][left])
			}
			left++
		}
	}

	return res
}

相似题目

题目 难度 考察点
59. 螺旋矩阵 II 中等 螺旋顺序生成矩阵
885. 螺旋矩阵 III 中等 螺旋遍历变体
2326. 螺旋矩阵 IV 中等 螺旋顺序填充链表
498. 对角线遍历 中等 矩阵按规律遍历
48. 旋转图像 中等 矩阵原地变换
73. 矩阵置零 中等 矩阵遍历+标记
289. 生命游戏 中等 矩阵原地模拟
本文作者:
本文链接: https://hgnulb.github.io/blog/2026/76110162
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!