顺(逆)指针填充数组/螺旋打印数组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);
} 总结:
解题思路同样适用于按照顺时针打印数组,逆时针打印数组。容易出错的有两点:
一:拐角处坐标的调整,可以在纸上确定三个拐角处坐标变化。
二:为了防止出现重复遍历的情况,可以使用一个计数器记录已经遍历的元素客诉。尤其遍历的矩阵不是由两行两列的时候。

京公网安备 11010502036488号