54. 螺旋矩阵
描述:
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
思路:
-
和59题螺旋矩阵II类似, 也是遍历一个矩阵
-
过程类似:
-
基础相关数据, 矩阵的宽:
n = matrix[0].size(), 矩阵的高:m = matrix.size(), 矩阵左初始边界:left = 0, 右初始边界:right = n - 1, 矩阵上初始边界:top = 0, 下初始边界:bottom = m - 1, 接收数据的数组:vector<int> ret -
将上述的基础数据列清楚, 那么就比较好遍历矩阵了.
-
遍历上边,
top不变,left++, 直到left == right// 上: 从左至右 for (int i{left}; i <= right; i++) { ret.push_back(matrix[top][i]); } -
遍历右边,
right不变,top++, 直到top == bottom// 右: 从上至下 for (int i{top + 1}; i <= bottom; i++) { ret.push_back(matrix[i][right]); } -
遍历下边,
bottom不变,right--, 直到right == left// 下: 从右至左 for (int i{right - 1}; i > left; i--) { ret.push_back(matrix[bottom][i]); } -
遍历左边,
left不变,bottom--, 直到bottom == top// 左: 从下至上 for (int i{bottom}; i > top; i--) { ret.push_back(matrix[i][left]); }
-
-
上面的步骤相当于遍历了一圈, 遍历一圈后, 需要将
top++,right--,bottom--,left++, 并开始下一圈遍历. -
最后注意一些细节, 这题就过了.
-
代码:
* [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)。除了输出数组以外,空间复杂度是常数。