矩阵的“之"字遍历ZigZag打印

题目描述

给一个m*n矩阵,请以“之"字型进行遍历输出,

{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }输出结果为:1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16 

{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }

输出:1 2 5 9 6 3 4 7 10 11 8 12

分析

该题目跟我博客里的其他两篇关于矩阵的操作的思路很相似,大家感兴趣的可以参看这两篇进行对比查看:

矩阵顺时针旋转90度

做该题不能死扣每个点与下一个点之间的关系,这样就是陷入出力不讨好的怪圈中,应该从更高的层面去考虑,可以参考矩阵的旋转和矩阵的旋转打印那样的方法。当我们在遍历矩阵的时候发现,我们每次输出的数都是斜着的一行(左下方到右上方),所以我们每次可以将问题分解为,每次遍历一个斜行,至于方向是从左下到↗️右上,还是右上到↙️左下,我们可以使用一个bool类型的数据来记录,每次把这一个斜行输出完毕之后,就更换一下这个bool类型的数据即可。

在动手code之前,我们将解决方案分为两个函数,第一个函数将整个矩阵划分为(m+n-1)个斜行,我们只需要记录这一斜行的两端的座标(ax,ay)(bx,by)即可。再定义一个函数进行输出某一斜行的数据,其中传进去的bool值可以让它知道什么方向输出。

废话少数,show codes:

#include<iostream>
#include<vector>
using namespace std;


//输出斜线(ax,ay)到(bx,by)的一列内容,根据flag来确定输出打印的方向
void printLine(vector<vector<int>>matrix,int ax,int ay,int bx,int by,bool flag){
    //cout<<"("<<ax<<","<<ay<<"),("<<bx<<","<<by<<")"<<endl;
  if(flag){
    //从左下方往右上方移动(bx,by)->(ax,ay)
    while( bx >= ax){
      printf("%d ",matrix[bx][by]);
      bx--;
      by++;
    }
  }else{
    //从右上往左下移动
    while(ay >= by){
      printf("%d ",matrix[ax][ay]);
      ax++;
      ay--;
    }
  }
}

void printMatrixZig(vector<vector<int>>matrix){
  int m = matrix.size();
  int n = matrix[0].size();
  bool up2Down = true;
  int ax=0;
  int ay=0;
  int bx=0;
  int by=0;
  for(int i=0;i<m+n-1;i++)
  {
    printLine(matrix,ax,ay,bx,by,up2Down);
    if(i<m-1){
      bx++;
    }else{
      by++;
    }
    if(i<n-1){
      ay++;
    }else{
      ay=n-1;
      ax++;
    }
    up2Down = !up2Down;
  }
}

int main()
{
  vector<vector<int>>matrix={
  {1,2,3,4},
  {5,6,7,8},
  {9,10,11,12}
  };
  printMatrixZig(matrix);
  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章