[经典算法]优雅实现顺时针打印矩阵

来源:互联网 发布:金冠网络中介平台 编辑:程序博客网 时间:2024/05/19 16:22
记得这是我在Google面试的时候,被问到的一个问题。关于顺时针打印矩阵问题描述,大家可以搜索下题目,大致信息如下: 
给定一个m*n的矩阵,要求,从外层顺时针打印一直到打印完所有元素, 
如: 
1、2*2矩阵 
   1 2 
   3 4 

输出:1 2 4 3 

2、3*4矩阵 
   1 2 3 4 
   5 6 7 8 
   9 1 2 3 

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

乍一看,这道题挺简单,尤其在面试时,以最快速度写出代码为目标,直接用4个for循环手写代码。但在写的过程中,发现要注意的边界问题很多,但最后还是磕磕绊绊写完了。之后没再考虑了,直到最近偶然看到网上的一些解法,遂觉得是否有更优雅的写法。经过思考,其实只需要考虑矩阵的四个坐标,通过四个坐标的边界来控制即可。每次循环完最外层,四个边界缩小一层即可。最后再通过是否有打印输出作为最外层循环结束条件即可。这样一来,只通过一个for循环搞定,从而以最优雅的方法完美解决该问题。同时,最少的循环,避免复杂的边界判断。 

废话不多说,直接上代码,欢迎拍砖。
 

Java代码 
  1. public class Test {   
  2.           
  3.         private boolean valid(int cc, int m, int n){   
  4.                 if( cc >= m && cc <= n ){   
  5.                         return true;   
  6.                 }   
  7.                 return false;   
  8.         }   
  9.           
  10.         public void print(int m, int n, int a[][], boolean visited[][]){   
  11.                 int offsetX[] = new int[]{0,1,0,-1};   
  12.                 int offsetY[] = new int[]{10, -10};   
  13.                   
  14.                 int sX = 0, eX = n - 1;   
  15.                 int sY = 0, eY = m - 1;   
  16.                   
  17.                 boolean flag = false;   
  18.                 do{   
  19.                         if( sX > eX || sY > eY ){   
  20.                                 break;   
  21.                         }   
  22.                         int xTmp = sX;   
  23.                         int yTmp = sY;   
  24.                         forint ii = 0; ii < offsetX.length;){   
  25.                                 if( valid( xTmp, sY, eY) && valid(yTmp, sX, eX) && !visited[xTmp][yTmp]){   
  26.                                         System.out.print(a[xTmp][yTmp]+"\t");   
  27.                                         visited[xTmp][yTmp] = true;   
  28.                                         flag = true;   
  29.                                 }   
  30.                                   
  31.                                 if( valid(xTmp + offsetX[ii], sY, eY) && valid(yTmp + offsetY[ii], sX, eX) ){   
  32.                                         xTmp += offsetX[ii];   
  33.                                         yTmp += offsetY[ii];   
  34.                                 }else{   
  35.                                         ii++;   
  36.                                 }   
  37.                                   
  38.                         }   
  39.                         sX++;   
  40.                         eX--;   
  41.                         sY++;   
  42.                         eY--;   
  43.                 }while( flag );   
  44.         }   
  45.           
  46.         public static void main(String[] args) {   
  47.                 int a[][];   
  48.                 int m = (int)(Math.random() * 5)+1;   
  49.                 int n = (int)(Math.random() * 5)+1;   
  50.                   
  51. //                m = 10;   
  52. //                n = 1;   
  53.                   
  54.                 a = new int[m][n];   
  55.                 boolean visited[][] = new boolean[m][n];   
  56.                   
  57.                 System.out.println( m + " * " + n);   
  58.                   
  59.                 forint i = 0; i < m; i++ ){   
  60.                         forint j = 0; j < n; j++ ){   
  61.                                 int tmp = (int)(Math.random() * 10);   
  62.                                 a[i][j] = tmp;   
  63.                                 visited[i][j] = false;   
  64.                                 System.out.print(tmp+"\t");   
  65.                         }   
  66.                         System.out.println();   
  67.                 }   
  68.                 System.out.println();   
  69.                   
  70.                 System.out.println("顺时针打印:");   
  71.                 Test t = new Test();   
  72.                 t.print(m, n, a, visited);   
  73.         }   
  74.           
  75. }   


不用考虑打印方向,只通过一个for循环,优雅完成顺时针打印任务。尽可能少的判断边界条件,从而减少错误概率。
0 0
原创粉丝点击