顺(逆)指针填充数组/螺旋打印数组MXN:
输入两个数M ,N:
输出两个填充的数组:
样例输入:
3 4
样例输出:
1 2 3 4
10 11 12 5
9 8 7 6
//逆时针螺旋生成一个M*N数组 //顺时针螺旋生成一个M*N数组 //顺逆交替生成一个M*N数组 #include<iostream> #include<vector> using namespace std; //注意填充时三个拐外处,并且循环一圈,最后一个元素不要覆盖第一个元素 void clockWiseFill(vector<vector<int>> &res,int M,int N) { int i ,j;//作为循环变量 int mb = 0,nb = 0; //mb,nb作为当前循环矩形的最上面和左边 int me =M,ne = N;//me,ne作为当前循环矩形中的最下边和最后边 int cnt =1;//cnt作为当前循环数值 while(cnt<=M*N) { //cout<<mb<<","<<nb<<" "<<me<<","<<ne<<","<<cnt<<endl; i = mb; j= nb; while(cnt<=M*N&&j < ne)res[i][j++] = cnt++;//上边 i++;j--; while(cnt<=M*N&&i< me) res[i++][j] = cnt++;//右边 i--;j--; while(cnt<=M*N&&j>=nb) res[i][j--] = cnt++;//下边 i--;j++; while(cnt<=M*N&&i>mb) res[i--][j] = cnt++;//左边 mb++; nb++; me--; ne--; } } void counterclockWiseFill(vector<vector<int>> &res,int M,int N) { int i ,j;//作为循环变量 int mb = 0,nb = 0; //mb,nb作为当前循环矩形的最上面和左边 int me =M,ne = N;//me,ne作为当前循环矩形中的最下边和最后边 int cnt =1;//cnt作为当前循环数值 //填充矩阵 while(cnt<=M*N) { //cout<<mb<<","<<nb<<" "<<me<<","<<ne<<","<<cnt<<endl; i = mb; j= nb; while(cnt<=M*N&&i<me) res[i++][j] = cnt++;//左边 i--;j++; while(cnt<=M*N&&j<ne) res[i][j++] = cnt++;//下边 i--;j--; while(cnt<=M*N&&i>=mb) res[i--][j] = cnt++;//右边 i++;j--; while(cnt<=M*N&&j>nb)res[i][j--] = cnt++;//上边 mb++; nb++; me--; ne--; } } //输出矩阵 void print(vector<vector<int>> res,int M,int N) { for(int i = 0;i < M;i++) { for(int j = 0;j <N;j++) { cout<<res[i][j]<<" "; if(j!=N-1) cout<<" "; } cout<<endl; } } void clockAndCounterkWise(vector<vector<int>> &res,int M,int N) { int i ,j;//作为循环变量 int mb = 0,nb = 0; //mb,nb作为当前循环矩形的最上面和左边 int me =M,ne = N;//me,ne作为当前循环矩形中的最下边和最后边 int cnt =1;//cnt作为当前循环数值 int total=M*N; bool flag = true; while(cnt <= total) { i = mb,j = nb; if(flag) { //上边 while(cnt<=total&&j<ne)res[i][j++]=cnt++; i++;j--; //右边 while(cnt<=total&&i<me)res[i++][j]= cnt++; i--;j--; //下边 while(cnt<=total&&j>=nb)res[i][j--]= cnt++; i--;j++; //左边 while(cnt<=total&&i>mb)res[i--][j]= cnt++; flag = false; } else { //左边 while(cnt<=total&&i<me)res[i++][j]= cnt++; i--;j++; //下边 while(cnt<=total&&j < ne)res[i][j++]=cnt++; i--;j--; //右边 while(cnt<=total&&i>=mb)res[i--][j]=cnt++; //上边 i++;;j--; while(cnt<=total&&j>nb)res[i][j--]=cnt++; flag = true; } mb++; nb++; me--; ne--; } } int main() { int M,N; cin>>M>>N; vector<vector<int>> res; for(int i = 0;i < M;i++) { vector<int> temp(N,0); res.push_back(temp); } //逆时针螺旋生成一个M*N数组 clockWiseFill(res,M,N); print(res,M,N); //顺时针螺旋生成一个M*N数组 // counterclockWiseFill(res,M,N); // print(res,M,N); //顺逆交替生成一个M*N数组 // clockAndCounterkWise(res,M,N); // print(res,M,N); }
总结:
解题思路同样适用于按照顺时针打印数组,逆时针打印数组。容易出错的有两点:
一:拐角处坐标的调整,可以在纸上确定三个拐角处坐标变化。
二:为了防止出现重复遍历的情况,可以使用一个计数器记录已经遍历的元素客诉。尤其遍历的矩阵不是由两行两列的时候。