面试题20:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如输入一个矩阵:
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
分析:这道题分析难度个人感觉确实很大,首先结束条件是什么?没看答案之前一点头绪没有,完全不知道怎么去结束最后一圈的循环。这是做题一来第一次连思路都没有的题目。
详细分析:一圈遍历分为4个步奏
1---- | ---- | ---- | ---> |
^4 | |2 | ||
| | | | ||
<--- | ---- | ----3 | V |
这是最完整的一圈,也比较好控制就是到矩阵的边界也计较直观,但是最后一圈有以下几种情况:
1)--------------->
|
<-------- V
2)|
|
V
3)---------------->
如果单从下标上来分析确实找不到头绪,因为结束出的下标没有规律。看过答案后发现,不是去找结束的那个点而是去找什么时候是最后一圈,并把单个的下标组合成坐标。这样结束的条件就可以看出:columns>X*2&&rows>Y*2,分析到这里代码也就写出来了。
void PrintMatrix(int** numbers,int columns,int rows)
{
if(numbers==NULL || columns<=0||rows<=0)
{
return ;
}
int start = 0;
while(columns>start*2&&rows>start*2)
{
PrintMatrixInCircle(numbers,columns,rows,start);
}
}
PrintMatrixInCircle(int** numbers,int columns,int rows,int start)
{
int endX = columns -1 -start;
int endY = rows -1 - start;
//左→右
for(int i=start;i<=endX;++i)
{
int number = numbers[start][i];
printNumber(number);
}
//上→下
if(start<endY)
{
for(int i=start+1;i<=endY;++i)
{
int number = numbers[i][endX];
printNumber(number);
}
}
//右→左
if(start<endX && start<endY)
{
for(int i=endX-1;i>=start;--i)
{
int number = numbers[endY][i];
printNumber(number);
}
}
//下→上
if(start<endX && start<endY-1)
{
for(int i=endY-1;i>=start+1;--i)
{
int number = numbers[i][start];
printNumber(number);
}
}
}