题目的主要难度在于如何控制遍历方向的变化。首先,可以考虑建立两个方向数组(一个控制行的移动,另一个控制列的移动)。另外,由于题目的要求,这两个方向数组的控制的移动方向必须按照“右、下、左、上”的顺序排列。这样,方向的选取就可以按照“循环位移”的方式来进行,即当前位置加1后再对4取模。
那么,另一个问题是如何发现改变方向的时机呢?很多人容易想到根据当前可访问的行或列的界限来设置循环控制。然而这样设计起来比较复杂。比较简洁的方式就是设置另外一个同规模的访问数组。这样,对于数组的访问就会像我们在做“迷宫、地图”类问题时一样了。
具体代码如下:
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
vector<int> ans;
if(matrix.empty()) return ans;
int n = matrix.size(), m = matrix[0].size();
vector<vector<int>> visit(n, vector<int> (m, 0));
//这里方向数组的设置是固定的,即右、下、左和上
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int x = 0, y = 0, j = 0; //j用来控制方向
for(int i = 0; i < n * m; i++){
ans.push_back(matrix[x][y]);
visit[x][y] = 1;
x += dx[j], y += dy[j];
if(x >= 0 && x < n && y >= 0 && y < m && !visit[x][y]) continue; //未发生越界或重复访问则继续
else{ //否则更改方向
x -= dx[j], y -= dy[j];
j = (j + 1) % 4;
x += dx[j], y += dy[j];
}
}
return ans;
}
};