题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
方法一:
用四个数分别表示第一行,最后一行,第一列,最后一列,旋转依次打印第一行,最后一列,最后一行,第一列,一次旋转打印结束后,丢弃最外面一层,行列分别前进后退。
!!!注意:为防止出现单行、单列而导致有些元素打印两次的问题,需要加入条件判断,使单行时,行打印一遍;单列时,列打印一遍。
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
int row=matrix.size();
int col=matrix[0].size();
vector<int>result;
if(row==0||col==0)
return result;
int lef=0,rig=col-1,top=0,bot=row-1; // 定义四个关键变量,表示左上和右下的打印范围
while((lef<=rig)&&(top<=bot))
{
for(int i=lef;i<=rig;i++)
result.push_back(matrix[top][i]);
for(int i=top+1;i<=bot;i++)
result.push_back(matrix[i][rig]);
if(bot>top) //防止单行时,行打印两遍
{
for(int i=rig-1;i>=lef;i--)
result.push_back(matrix[bot][i]);
}
if(rig>lef) //防止单列时,列打印两遍
{
for(int i=bot-1;i>=top+1;i--)
result.push_back(matrix[i][lef]);
}
lef++;rig--;top++;bot--;
}
return result;
}
};
方法二:
一个循环就能搞定:
1.先横向正走,再纵向正走,再横向反走,再纵向反走,再横向正走。。。循环往复。
2.横向走完后,纵向走的最大距离减一,纵向走完后,横向的最大距离减一。
3.横向走的初始距离为矩阵的宽度,纵向走的初始距离为矩阵的高度减一(其实是因为2的原因减一)。
为保持初始的横向正走的距离为矩阵宽度,初始的下标设为0,-1。然后就可以发车了。
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
int l=matrix[0].size(); //车在当前这一行能走的最大距离
int w=matrix.size(); //车在当前这一列能走的最大距离
int posx=-1; //车的当前所处的列坐标,初始化为-1,这样+矩阵宽度刚好到边界
int posy=0; //车当前所处的行坐标。
int pathx=1; //车在当前这一行所走的距离,不能大于l。等于0则纵向走。
int pathy=0; //车在当前这一列所走的距离,不能大于w。等于0则横走。
int flag=1; //车的反向转弯标志。
vector<int> vec;
while(l > 0 && w > 0) //当横向纵向一个无路可走,就退出循环
{
vec.push_back(matrix[posy+pathy][posx+pathx]);//把车当前位置的数据存入
if(pathx != 0) //pathx !=0 代表目前正在横向走
{
if( abs(pathx + flag) <= l) //判断是不是撞墙了,压线了
pathx=pathx+flag; //注意flag,因为会反向。事实上,每次纵向走完就反向
else
{
pathx=0; //横向不走了
pathy=flag; //让纵向开始走(flag不变是因为横向走完不会反向)
posx=posx+flag*l; //更新纵向走的初始位置
w--; //纵向能走的距离减一,因为这一行走完,少了一列。
}
}
else if(pathy != 0) //横向走完,pathx设0,pathy设为1或-1,可以走了
{
if( abs(pathy +flag) <= w )
pathy=pathy+flag;
else
{
pathy=0;
posy=posy+flag*w;
flag=flag*(-1); //上面和横向一样,这里要注意,以为每次纵向走完,要反向
pathx=flag;
l--;
}
}
}
return vec;
}
};