这个题挺有趣的,螺旋数组,意思是给定一个m*n的数组,按照螺旋的形状去遍历这个数组,求出螺旋遍历的数组的顺序。
还记得前面的那个旋转数组的题吗?这个题和那个题异曲同工,主要的思路是:先遍历一圈,然后依次遍历里面的圈。不过这道题需要注意的旋转数组的题要复杂一些,条件的控制复杂一些,我举个例子吧:
我们可以顺时针方向遍历数组,就上上图所示一样;不过上面两个数组有什么特点吗?都是遍历到最后一次的时候只剩下一列或者一行,像这种情况是最容易出错的地方,我们很容易忽略了这些。当我们遍历到最后一趟的时候,需要注意一些问题。我们的每一趟遍历都分为四步,第一步是横向向前遍历,第二步是竖直向下遍历,第三步是横向往回遍历,第四步是竖直向上遍历;所以像上图中的两种情况,在第三步第四步中容易导致错误,错误的原因是重复计算了一些位置。下面我给出代码,大家可以看看,第三步和第四步的处理。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix)
{
/* 螺旋数组 */
vector<int> ret;
ret.clear();
int x = matrix.size(); //行
if (x == 0)
{ //空
return ret;
}
else if (x == 1)
{ //只有一行
for (int i = 0; i < matrix[0].size(); ++i)
{
ret.push_back(matrix[0][i]);
}
return ret;
}
int y = matrix[0].size();//列
if (y == 1)
{ //只有一列
for (int i = 0; i < x; ++i)
{
ret.push_back(matrix[i][0]);
}
return ret;
}
for (int i = 0; i <= (y-1) / 2; ++i)
{
if (i <= (x-1) / 2)
{ // 行和列都满足一定条件才能调用遍历函数
_traverse(matrix, ret, i, x, y);
}
}
return ret;
}
void _traverse(vector<vector<int>>& ma, vector<int>&ret, int pos, int x, int y)
{ //pos为其实位置,该位置 x==y
for (int step1 = pos; step1 < y - pos; ++step1)
{
ret.push_back(ma[pos][step1]);
}
for (int step2 = pos + 1; step2 < x - pos; ++step2)
{
ret.push_back(ma[step2][y - pos - 1]);
}
for (int step3 = y - pos - 2; step3 >= pos && x-pos-1 > pos; --step3)
{ //最后只剩一行的时候易错,行重复
ret.push_back(ma[x-pos-1][step3]);
}
for (int step4 = x - pos - 2; step4 > pos && y-pos-1 > pos ; --step4)
{ //最后只剩一列的时候易出错,列重复
ret.push_back(ma[step4][pos]);
}
}
};
最后的结果如下: