题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.
如图所示:
实际上,就是每一次打印一圈:第一圈的左上角为(0,0),第二圈的左上角为(1,1),……,第n圈的左上角为(n-1,n-1);
接下来,多分析矩阵,找出一些规律。
对于4x4矩阵,它的最后一圈的左上角为(1,1),可以发现:4 > 1*1;
对于5x5矩阵,它的最后一圈(只有一个数字),左上角为(2,2),可以发现:5 > 2*2;
对于6x6矩阵,它的最后一圈的左上角为(2,2),可以发现:6 > 2*2;
……
不难得出,对于n*n矩阵,打印的最后一圈的左上角若为(x,x),则:n > x*x。
所以现在得出了按圈数循环的结束条件:行数或者列数必须大于当前左上角坐标之积。
所以目前需要知道如何打印单圈?
打印单圈分四步:
1.从左往右
2.从上到下
3.从右往左
4.从下到上
但是当打印最后一圈时,并不是一定都走这四步的。
思考一下:
如果最后一圈只有一行了,那就只需要走第一步,不需要走第二步了;
要走第二步,至少需要列数为二;
而要走第三部步,则至少需要行数为二;
要走第四步,则至少需要三行两列。
所以第一步一定要走。
接下来是代码,start是表示第几圈。
//打印单圈 void PrintMatrixInCircle(vector<vector<int> > matrix, vector<int>& ret, int start) { int endx = matrix[0].size() - 1 - start; int endy = matrix.size() - 1 - start; //从左到右 for (size_t i = start; i <= endx; i++) ret.push_back(matrix[start][i]); //从上到下 if (endy > start) { for (size_t i = start + 1; i <= endy; i++) ret.push_back(matrix[i][endx]); } //从右到左打一行 if (endx > start && endy > start) { for (int i = endx - 1; i >= start; i--) { ret.push_back(matrix[endx][i]); } } //从下到上打印一列 if (endy - start > 1 && endx > start) { for (int i = endy - 1; i > start; i--) { ret.push_back(matrix[i][start]); } } } vector<int> printMatrix(vector<vector<int> > matrix) { vector<int> ret; int start = 0; int row = matrix[0].size();//行 int col = matrix.size();//列 //n*n矩阵,最后一圈左上角为(a,a),通过规律,n > a*a,这就是循环继续条件 while (row > start * 2 && col > start * 2) { PrintMatrixInCircle(matrix, ret, start); ++start; } return ret; }