LeetCode 剑指 Offer 29. 顺时针打印矩阵

题目描述

剑指 Offer 29. 顺时针打印矩阵

image-20250510231223304

image-20250510231242071

image-20241107205533289

思路分析

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

核心思路

  • 设定四个边界变量 topbottomleftright,分别表示当前未遍历区域的上、下、左、右边界。
  • 按照「右 → 下 → 左 → 上」的顺序依次遍历当前层的元素。
  • 每遍历完一个方向后,立即收缩对应边界,并检查边界是否仍合法,避免重复遍历。
  • 循环条件为 top <= bottom && left <= right,当边界交叉时停止。


复杂度分析

  • 时间复杂度:O(mn),其中 m 和 n 分别表示矩阵的行数和列数,每个元素恰好被访问一次。
  • 空间复杂度:O(1),不计入存储结果的数组,只使用了常数个边界变量。
class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0) {
            return new int[0];
        }

        int m = matrix.length;
        int n = matrix[0].length;
        int[] res = new int[m * n];
        int idx = 0;

        // 初始化四个边界
        int top = 0, bottom = m - 1, left = 0, right = n - 1;

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

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

            // 从右到左遍历下边界行(需检查上下边界是否仍合法)
            if (top <= bottom) {
                for (int i = right; i >= left; i--) {
                    res[idx++] = matrix[bottom][i];
                }
                bottom--;
            }

            // 从下到上遍历左边界列(需检查左右边界是否仍合法)
            if (left <= right) {
                for (int i = bottom; i >= top; i--) {
                    res[idx++] = matrix[i][left];
                }
                left++;
            }
        }

        return res;
    }
}
func spiralOrder(matrix [][]int) []int {
	var res []int
	if len(matrix) == 0 {
		return res
	}

	// 初始化四个边界
	top, bottom := 0, len(matrix)-1
	left, right := 0, len(matrix[0])-1

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

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

		// 从右到左遍历下边界行(需检查上下边界是否仍合法)
		if top <= bottom {
			for i := right; i >= left; i-- {
				res = append(res, matrix[bottom][i])
			}
			bottom--
		}

		// 从下到上遍历左边界列(需检查左右边界是否仍合法)
		if left <= right {
			for i := bottom; i >= top; i-- {
				res = append(res, matrix[i][left])
			}
			left++
		}
	}

	return res
}

相似题目

题目 难度 考察点
54. 螺旋矩阵 中等 矩阵模拟、边界收缩
59. 螺旋矩阵 II 中等 矩阵模拟、螺旋填充
885. 螺旋矩阵 III 中等 矩阵模拟、方向数组
2326. 螺旋矩阵 IV 中等 矩阵模拟、链表填充
498. 对角线遍历 中等 矩阵模拟、方向交替
73. 矩阵置零 中等 矩阵原地修改
48. 旋转图像 中等 矩阵原地旋转
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/63222519
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!