顺时针打印矩阵
2016-04-25 23:01
330 查看
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
这个题有两种方法,剑指offer里使用的是第一种方法,即每次打印一圈,第i圈从位置(i,i)开始打印,但是这种方法只适用于方阵,或者列数大于行数的矩阵。对于只包含一列的矩阵会有错误。
第二种方法是,转圈法,设置4个标志位表示四个方向,用int[][] book访问矩阵来表示对应的位是否已经访问,这种方法的空间复杂度为O(m*n),如果还有其他方法,也可以在给出提示,不胜感激。
方法二:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
这个题有两种方法,剑指offer里使用的是第一种方法,即每次打印一圈,第i圈从位置(i,i)开始打印,但是这种方法只适用于方阵,或者列数大于行数的矩阵。对于只包含一列的矩阵会有错误。
第二种方法是,转圈法,设置4个标志位表示四个方向,用int[][] book访问矩阵来表示对应的位是否已经访问,这种方法的空间复杂度为O(m*n),如果还有其他方法,也可以在给出提示,不胜感激。
方法一:
//顺时针打印矩阵 public ArrayList<Integer> printMatrix(int [][] matrix) { if(matrix==null || matrix.length<=0 || matrix[0].length<=0){ return null; } ArrayList<Integer> res = new ArrayList<Integer>(); // 1.计算需要打印多少次,即打印多少个圈 int printRow = (matrix.length+1)/2;//注意在计算打印次数是加1,这样在1行时,打印一次,在4行时打印两次,在5行时打印三次 int row = matrix.length,col = matrix[0].length; for(int i=0;i<printRow;i++){ //第i次,从(i,i)开始打印 printCircle(matrix,res,i,row,col); } return res; } //打印第i圈 public void printCircle(int[][] matrix,ArrayList<Integer> res,int i,int row,int col){ int right = col-1-i; int down = row-1-i; //-> for(int left = i;left<=right;left++){ res.add(matrix[i][left]); } //up down,记住这一行的最后一个已经被打印了,从下一行开始打印 for(int up=i+1;up<=down;up++){ res.add(matrix[up][right]); } //最后一列的最后一个已经被打印了,从次最后列开始打印 for(int r=right-1;r>=i;r--){ res.add(matrix[down][r]); } for(int b=down-1;b>i;b--){ res.add(matrix[b][i]); } }
方法二:
//顺时针打印矩阵 public ArrayList<Integer> printMatrix(int [][] matrix) { ArrayList<Integer> res = new ArrayList<Integer>(); if(matrix.length==0 || matrix[0].length==0){ return res; } int width = matrix[0].length; int high = matrix.length; //top,down,left,right; //四个方向分别用1,2,3,4来表示 int direct = 4; boolean[][] book = new boolean[high][width]; int i=0,j=-1; while(true){ //四个方向都访问完毕 if((j+1<width&&book[i][j+1]||j+1==width) //右 && (i+1<high&&book[i+1][j]||i+1==high) //下 && (i-1>=0&&book[i-1][j]||i-1==-1) //上 && (j-1>=0&&book[i][j-1]||j-1==-1)){//左 break; } //根据方向来进行遍历 switch (direct){ case 4: while(j+1<width&&!book[i][j+1]){ book[i][j+1] = true; res.add(matrix[i][j+1]); j++; } direct = 2; break; case 2: while(i+1<high&&!book[i+1][j]){ book[i+1][j] = true; res.add(matrix[i+1][j]); i++; } direct = 3; break; case 3: while(j-1>=0&&!book[i][j-1]){ book[i][j-1] = true; res.add(matrix[i][j-1]); j--; } direct = 1; break; case 1: while(i-1>=0&&!book[i-1][j]){ book[i-1][j] = true; res.add(matrix[i-1][j]); i--; } direct = 4; } } return res; }
相关文章推荐
- EventBus的简单使用
- SVD Recommendation System in Ruby
- 【C++】顺序表
- http与https的区别
- Linux下shell颜色配置
- Linux高级管理(三)
- 【Linux】df命令 ,查看磁盘容量。
- STM32 can not read project
- 06-图2 Saving James Bond - Easy Version
- 编程时候的听到的优美歌曲
- SpringMVC3.1+MyBatis3.2+Mysql5.5+ExtJS4.2实现角色权限管理系统
- 关于android.mk文件编写
- 嵌入式Linux kernel LOGO的更换方法
- 线段树pushdown的时候一定要记得把lazy标记一起下传!
- 从头认识多线程-2.3 脏读(DirtyRead)
- 4月15日作业总结,成绩(暂未发布)
- javascript中的slice
- iOS 计算某个日期一定天数后的新日期 —— HERO博客
- 51nod 1118 机器人走方格
- 递归思想