题目
给你一个 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
我是直接模拟的,想象一个机器人从 [0, 0]
位置开始走,初始方向向右,每当他遇到下列情况之一,就改变方向:
- 按照原方向走,下一步会越界
- 按照原方向走,下一步是已走过的地方
方向改变的规则是按照右、下、左、上的次序依次循环。
以下是具体实现:
- 每调用一次
traverse
函数,机器人先将当前格的数字填入答案,然后前进一步,并修改当前所在坐标 - 使用
traversed
矩阵来记录机器人走过的坐标 - 一共需要走
m
∗
n
m*n
m∗n 步,所以需要调用
m
∗
n
m*n
m∗n 次
traverse
函数
时间复杂度:
O
(
m
n
)
O(mn)
O(mn)
空间复杂度:
O
(
m
n
)
O(mn)
O(mn)
C++ 代码
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[0].empty())
return vector<int>();
const int Y = matrix.size(), X = matrix[0].size();
vector<vector<bool>> traversed(Y, vector<bool>(X, false));
vector<int> ans;
int y = 0, x = 0, direct = 0, sz = Y * X;
for (int i = 0; i < sz; ++i)
traverse(matrix, traversed, Y, X, y, x, direct, ans);
return ans;
}
void traverse(vector<vector<int>>& matrix, vector<vector<bool>>& traversed,
const int Y, const int X, int& y, int& x,
int& direct, vector<int>& ans) {
traversed[y][x] = true;
ans.push_back(matrix[y][x]);
int nextY = y + direction[direct][0];
int nextX = x + direction[direct][1];
if (nextY < 0 || nextY >= Y || nextX < 0 || nextX >= X
|| traversed[nextY][nextX]) {
direct = (direct + 1) % 4;
nextY = y + direction[direct][0];
nextX = x + direction[direct][1];
}
y = nextY;
x = nextX;
}
private:
const vector<vector<int>> direction{
{0, 1},
{1, 0},
{0, -1},
{-1, 0},
};
};