题意
传送门 面试题29. 顺时针打印矩阵
题解
构造一个顺时针方向的正方形边向量,观察到打印的下一个方向决定于前一个方向以及位置是否合法。
d v = { [ 0 , 1 ] , [ 1 , 0 ] , [ 0 , − 1 ] , [ − 1 , 0 ] } dv=\{[0,1],[1,0],[0,-1],[-1,0]\} dv={[0,1],[1,0],[0,−1],[−1,0]}
设上一次打印方向为 p r e pre pre 则下一次打印方向应该按 d v [ ( p r e + 0 ) % 4 ] , … , d v [ ( p r e + 3 ) % 4 ] dv[(pre+0)\%4],\dots,dv[(pre+3)\%4] dv[(pre+0)%4],…,dv[(pre+3)%4] 的优先顺序判断下一个位置是否合法。 d f s dfs dfs 求解即可。
class Solution
{
public:
int n, m;
vector<int> res;
vector<vector<int>> used;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
void dfs(int x, int y, int pre, vector<vector<int>> &mat)
{
res.push_back(mat[x][y]);
used[x][y] = true;
int p = (pre + 3) % 4;
for (int i = 0; i < 4; i++)
{
int now = (p + i) % 4;
int nx = x + dx[now], ny = y + dy[now];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && !used[nx][ny])
{
dfs(nx, ny, now, mat);
break;
}
}
}
vector<int> spiralOrder(vector<vector<int>> &matrix)
{
if (matrix.size() == 0 || matrix[0].size() == 0)
return res;
n = matrix.size(), m = matrix[0].size();
used.resize(n, vector<int>(m, 0));
dfs(0, 0, 0, matrix);
return res;
}
};