本文共 2322 字,大约阅读时间需要 7 分钟。
最近在笔试中遇到一道蛇形矩阵的题,笔试时没做出来,回来思考良久才终于琢磨出来,解法并不是最优,只是留在此处备忘!
常见的蛇形矩阵是Z型矩阵,如:
1 2 4
3 5 7
6 8 9
我笔试时遇到的是环形循环矩阵,如:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
一开始一直没找到规律,想了很久之后,发现每次行列切换(拐角)是可以用表达式很好的表达的。发现规律后,代码也就很简单的出来;如下:
void fillSnakeArr() { int colsIndex = 0, rowsIndex = 0; //行列序号 bool fillFlag = true; //true代表按行开始,false代表按列进行 int FilledNum = 1; //已经填充的数量 int turnNum = 0; //切换方向的次数 int nextRows = 0, nextCols = 0; //下一个方向的行列数 int arrSize = width*width; //矩阵大小 /*蛇形矩阵的拐点的坐标变换 * (nextRows=rowsIndex+1,nextCols=colsIndex-1 ) * *---------------* * (nextRows=rowsIndex+1,nextCols=colsIndex+1) * | | * | | * | | * | | * | |(nextRows=rowsIndex-1,nextCols=colsIndex-1) * *---------------* * (nextRows=rowsIndex-1,nextCols=colsIndex+1) */ while (1) { //沿列方向递增,行不变 if (turnNum%4==0) { for (rowsIndex=nextRows,colsIndex=nextCols; colsIndex < width;colsIndex++) { if (Arr[rowsIndex][colsIndex] == 0) { Arr[rowsIndex][colsIndex] = FilledNum++; } else break; } //下一个方向的坐标索引,-->|| nextRows = rowsIndex+1; nextCols = colsIndex - 1; //改变方向 turnNum++; } //沿行方向递增,列不变 else if (turnNum%4==1) { for (colsIndex = nextCols, rowsIndex = nextRows; rowsIndex < width; rowsIndex++) { if (Arr[rowsIndex][colsIndex] == 0) Arr[rowsIndex][colsIndex] = FilledNum++; else break; } //下一个方向的坐标 <--|| nextRows = rowsIndex - 1; nextCols = colsIndex - 1; turnNum++; } //沿列方向递减,行不变 else if (turnNum%4==2) { for (rowsIndex = nextRows,colsIndex = nextCols; colsIndex >= 0;colsIndex--) { if (Arr[rowsIndex][colsIndex] == 0) Arr[rowsIndex][colsIndex] = FilledNum++; else break; } //下一个方向的坐标 ||<-- nextRows = rowsIndex - 1; nextCols = colsIndex + 1; turnNum++; //改变方向 } //沿行方向递减,列不变 else if (turnNum%4==3) { for (colsIndex = nextCols,rowsIndex = nextRows; rowsIndex >= 0;rowsIndex--) { if (Arr[rowsIndex][colsIndex] == 0) Arr[rowsIndex][colsIndex] = FilledNum++; else break; } //下一个方向的坐标 ||--> nextRows = rowsIndex + 1; nextCols = colsIndex + 1; turnNum++; //改变方向 } if (FilledNum > arrSize) break; } }运行结果:
总结:沉下心,发现规律才是解决问题的关键!