解读这道题时,可以描述为以单位距离为步长,以[0,0]为起始位置的顺时针遍历矩阵,个人感觉下面这种解法较之原来的解法更加容易理解。其遍历矩阵的规律有:
- 右、下、左、上四个方向为一个循环周期。
- 在每个方向上遍历元素的初始个数是numArr=[clomns,rows-1,clomns-1,rows-2],并且在每次经过一个周期后,numArr的所有值全部减去2(形象化就是每次拿掉最外面那个框)之后,就是下一次循环需要在四个方向遍历的元素个数,其中rows为二维矩阵的行数,clomns为列数。
- 终止条件,numArr数组的当前元素==0,很明显numArr[i]==0时,已经没有需要遍历的元素了。
基于以上的3条规律,我们便可以轻松的写代码了,源代码如下:
/*20题,顺时针打印矩阵*/
#include<stdio.h>
void printArrClockwise(int rows,int clomns,int arr[][3]){
int ori[]={ //存储每一圈4次遍历的次数,一圈之后,全部减去2
clomns,rows-1,clomns-1,rows-2
};
int delx[]={ //4个方向上x值的变化步长
0,1,0,-1
};
int dely[]={ //4个方向上y值变化的步长
1,0,-1,0
};
int tempx=0; //初始x,y坐标
int tempy=-1; //需要注意
int i=0,j=0;
//printf("%d ",arr[tempx][tempy]);
while(1){
for(i=0;i<4;i++){
if(ori[i]==0){
printf("\n");
return;
}
else{
for(j=0;j<ori[i];j++){
tempx+=delx[i];
tempy+=dely[i];
printf("%d ",arr[tempx][tempy]);
}
}
}
for(i=0;i<4;i++){
ori[i]-=2;
}
}
//printf("\n"); //程序无法执行到这里
}
int main(int * argc,char ** argv){
int arr[5][3];
int i,j;
for(i=0;i<5;i++){
for(j=0;j<3;j++){
arr[i][j]=i+j;
printf("%d ",arr[i][j]);
}
printf("\n");
}
printArrClockwise(5,3,arr);
return 0;
}
当然,这道问题还可以变通,例如逆时针打印矩阵,这时候只需要将delx,dely步长数组的顺序调整一下即可。
最后,附上《剑指Offer–名企面试官精讲典型编程题》的源代码下载地址
以及该书作者何海涛的博客地址