Leetcode力扣解题记录--第54题(矩阵螺旋)

发布于:2025-07-24 ⋅ 阅读:(33) ⋅ 点赞:(0)

题目链接:54. 螺旋矩阵 - 力扣(LeetCode)

题目描述

给你一个 m 行 n 列的矩阵 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

题目作答

解决这个问题的核心思想是按层模拟。我们可以把矩阵想象成一个洋葱,从最外层开始,一层一层地向内“剥”,依次读取每一层的元素。

为了实现这一点,我们使用四个变量来定义当前遍历层的边界:

  • top:指向当前层的最顶行的行号。

  • bottom:指向当前层的最底行的行号。

  • left:指向当前层的最左列的列号。

  • right:指向当前层的最右列的列号。

整个遍历过程在一个循环中进行,循环的条件是 left <= right 并且 top <= bottom,这确保了边界内部仍然有元素可以遍历。在每一轮循环中,我们按顺时针顺序走完当前层的一圈:

  1. 从左到右:遍历上边界(top行),从 left 列到 right 列,将元素加入结果列表。完成之后,top 行已经被遍历完毕,所以我们将 top 加一,收缩上边界。

  2. 从上到下:遍历右边界(right列),从新的 top 行到 bottom 行。完成之后,right 列也被遍历完毕,所以我们将 right 减一,收缩右边界。

  3. 从右到左:遍历下边界(bottom行),从新的 right 列到 left 列。完成之后,bottom 行也处理完毕,所以 bottom 减一,收缩下边界。

  4. 从下到上:遍历左边界(left列),从新的 bottom 行到 top 行。完成之后,left 列也处理完毕,所以 left 加一,收缩左边界。

这个过程会不断重复,边界不断向内收缩,直到它们交错(left > right 或 top > bottom),此时所有元素都已被遍历。需要注意的是,在第3步和第4步执行前,要检查边界是否依然有效,以防止在处理只有一行或一列的矩阵时重复添加元素。

 

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) {
            return {};
        }

        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> result;
        
        // 定义四个边界
        int top = 0, bottom = m - 1, left = 0, right = n - 1;

        while (left <= right && top <= bottom) {
            // 1. 从左到右遍历上边界
            for (int j = left; j <= right; ++j) {
                result.push_back(matrix[top][j]);
            }
            top++; // 收缩上边界

            // 2. 从上到下遍历右边界
            for (int i = top; i <= bottom; ++i) {
                result.push_back(matrix[i][right]);
            }
            right--; // 收缩右边界

            // 检查边界是否依然有效,防止重复
            if (top <= bottom) {
                // 3. 从右到左遍历下边界
                for (int j = right; j >= left; --j) {
                    result.push_back(matrix[bottom][j]);
                }
                bottom--; // 收缩下边界
            }

            // 检查边界是否依然有效,防止重复
            if (left <= right) {
                // 4. 从下到上遍历左边界
                for (int i = bottom; i >= top; --i) {
                    result.push_back(matrix[i][left]);
                }
                left++; // 收缩左边界
            }
        }

        return result;
    }
};

 


网站公告

今日签到

点亮在社区的每一天
去签到