54. 螺旋矩阵

186 阅读2分钟

54. 螺旋矩阵

LeetCode

描述:

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

image-20211207124414292

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

思路:

  • 和59题螺旋矩阵II类似, 也是遍历一个矩阵

  • 过程类似:

    1. 基础相关数据, 矩阵的宽: n = matrix[0].size(), 矩阵的高: m = matrix.size(), 矩阵左初始边界: left = 0, 右初始边界: right = n - 1, 矩阵上初始边界: top = 0, 下初始边界: bottom = m - 1, 接收数据的数组: vector<int> ret

    2. 将上述的基础数据列清楚, 那么就比较好遍历矩阵了.

      1. 遍历上边, top不变, left++, 直到left == right

        // 上: 从左至右
        for (int i{left}; i <= right; i++)
        {
          ret.push_back(matrix[top][i]);
        }
        
      2. 遍历右边, right不变, top++, 直到top == bottom

        // 右: 从上至下
        for (int i{top + 1}; i <= bottom; i++)
        {
          ret.push_back(matrix[i][right]);
        }
        
      3. 遍历下边, bottom不变, right--, 直到right == left

        // 下: 从右至左
        for (int i{right - 1}; i > left; i--)
        {
          ret.push_back(matrix[bottom][i]);
        }
        
      4. 遍历左边, left不变, bottom--, 直到bottom == top

        // 左: 从下至上
        for (int i{bottom}; i > top; i--)
        {
          ret.push_back(matrix[i][left]);
        }
        
    3. 上面的步骤相当于遍历了一圈, 遍历一圈后, 需要将top++, right--, bottom--, left++, 并开始下一圈遍历.

    4. 最后注意一些细节, 这题就过了.

代码:

 * [54] 螺旋矩阵
 */

// @lc code=start
class Solution
{
public:
  vector<int> spiralOrder(vector<vector<int>> &matrix)
  {
    if (matrix.size() == 0 || matrix[0].size() == 0)
    {
      return {};
    }

    int m = matrix.size();
    int n = matrix[0].size();

    vector<int> ret;
    int top{0}, bottom{m - 1}, left{0}, right{n - 1};

    while (left <= right && top <= bottom)
    {
      
      for (int i{left}; i <= right; i++)
      {
        ret.push_back(matrix[top][i]);
      }

      // 右: 从上至下
      for (int i{top + 1}; i <= bottom; i++)
      {
        ret.push_back(matrix[i][right]);
      }

      if (left < right && top < bottom)
      {
        // 下: 从右至左
        for (int i{right - 1}; i > left; i--)
        {
          ret.push_back(matrix[bottom][i]);
        }

        // 左: 从下至上
        for (int i{bottom}; i > top; i--)
        {
          ret.push_back(matrix[i][left]);
        }
      }

      top++;
      right--;
      bottom--;
      left++;
    }

    return ret;
  }
};

时间复杂度:O(mn),其中 m 和 n 分别是输入矩阵的行数和列数。矩阵中的每个元素都要被访问一次。

空间复杂度:O(1)。除了输出数组以外,空间复杂度是常数。