题目
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
分析
这题思路挺简单,将矩阵由外而内分成若干层,每一层分成上下左右四个部分,依次遍历即可。难点主要是麻烦以及容易出错,关键在于处理两种边界条件:
- m!=n 时如何处理时,如何处理最内层(是一行或者一列)
- m==n但是为奇数时,如何处理最内层(是一个数字)
具体的解法见代码。
实现
class Solution {
public:
vector spiralOrder(vector>& matrix) {
if(matrix.empty() || matrix[0].empty()) return {};
vector ans;
int n = matrix.size();
int m = matrix[0].size();
int layers = (min(n,m)-1)/2;
int x, y;
for(int l=0; l<=layers; l++){
int left = l;
int right = m - l - 1;
int top = l;
int bottom = n - l - 1;
x = top; y = left;
while(y<=right){
ans.push_back(matrix[x][y]);
y++;
}
y = right; x++;
while(x<=bottom){
ans.push_back(matrix[x][y]);
x++;
}
if(bottom>top){
x = bottom; y--;
while(y>=left){
ans.push_back(matrix[x][y]);
y--;
}
}
if(lefttop){
ans.push_back(matrix[x][y]);
x--;
}
}
}
return ans;
}
};
思考
看了别人的解法,发现另一种思路也很好,而且感觉其结构更加高级。贴出来欣赏下:
class Solution {
public:
vector > visit;
vector res;
int add_x[4] = {0, 1, 0, -1};
int add_y[4] = {1, 0, -1, 0};
int d = 0;
vector spiralOrder(vector>& matrix) {
int m = matrix.size();
if (!m) return vector();
int n = matrix[0].size();
visit = vector >(m, vector(n, 0));
helper(matrix, 0, 0);
return res;
}
void helper(vector >& matrix, int x, int y) {
visit[x][y] = 1;
res.push_back(matrix[x][y]);
int m = matrix.size();
int n = matrix[0].size();
if (x + add_x[d] >= m || y + add_y[d] >= n || x + add_x[d] < 0 || y + add_y[d] < 0 || visit[x + add_x[d]][y + add_y[d]]) {
++d;
d %= 4;
}
if (x + add_x[d] >= m || y + add_y[d] >= n || x + add_x[d] < 0 || y + add_y[d] < 0 || visit[x + add_x[d]][y + add_y[d]]) return;
helper(matrix, x + add_x[d], y + add_y[d]);
}
};