顺(逆)指针填充数组/螺旋打印数组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);

 } 

总结:
解题思路同样适用于按照顺时针打印数组,逆时针打印数组。容易出错的有两点:
一:拐角处坐标的调整,可以在纸上确定三个拐角处坐标变化。
图片说明
二:为了防止出现重复遍历的情况,可以使用一个计数器记录已经遍历的元素客诉。尤其遍历的矩阵不是由两行两列的时候。