题目:
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列的数组,以螺旋式的方式访问,即绕圈式的访问,以顺时针方向,绕圈往里面依次访问,比如题目中的数组,访问的顺序就是1,2,3,6,9,8,7,4,5.
解题思路:
对于一个m*n的数组,我们每次以一个长方形的方式访问一圈,长方形的起始位置位于长方形的左上角的坐标,比如第一圈的起始坐标是(0,0),第二圈的起始位置将是(1,1)。如下图所示,蓝色的一个长方形代表以(0,0)为起点访问的一圈,红色的矩形代表以(1,1)为起点访问的一圈矩形,黄色的代表以(2,2)为起点访问的一圈。
假设该矩形的起始位置为(i,i),那么该矩形对应的横着的边上需要访问的个数就是row = n-2*i,对应的竖着的边上需要访问的元素个数就是line = m-2*i;访问一个矩形的元素时,可以分为四步去访问,即按照矩形的四条边去访问,如下图所示,分四步去访问矩形的元素。
但是需要考虑几种特殊情况:
- 第一种情况是矩形缩成了一条边,只剩下一条横着的边或者只剩下一条竖着的边,参见下图:
- 矩阵的第2步第4步访问的那两条边不存在,就是说,此时line = 2;参见下图:
以上。
代码如下:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size();
if(m == 0)return vector<int>();
int n = matrix[0].size();
vector<int> result;
int max_start = (((m-1)/2 < (n-1)/2)?((m-1)/2):((n-1)/2));
for(int start_i = 0; start_i <= max_start; ++start_i){
int line = m - 2*start_i;
int row = n - 2*start_i;
if(row == 1){
for(int j = 0; j < line; j++){
result.push_back(matrix[j + start_i][start_i]);
}
}
else if(line == 1){
for(int j = 0; j < row; j++){
result.push_back(matrix[start_i][j + start_i]);
}
}
else{
for(int j = start_i; j < row + start_i; ++j)
result.push_back(matrix[start_i][j]);
if(line >= 3){
for(int j = start_i + 1; j < line + start_i - 1; ++j)
result.push_back(matrix[j][start_i + row - 1]);
}
for(int j = start_i + row - 1; j >= start_i; --j)
result.push_back(matrix[start_i + line - 1][j]);
if(line >= 3){
for(int j = line - 2 + start_i; j > start_i; --j)
result.push_back(matrix[j][start_i]);
}
}
}
return result;
}
};