LeetCode OJ 54. Spiral Matrix
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
You should return [1,2,3,6,9,8,7,4,5]
.
【题目分析】
给定一个m行n列的矩阵M,求出这个矩阵螺旋形遍历的序列。
【思路】
我们是否能用控制下标来控制访问矩阵数据的顺序呢?我发现有点复杂~所以想一圈一圈来对矩阵进行序列化,这也是我首先想到的一个比较容易理解的方法。
1. 首先我们确定一个矩阵可以被遍历的圈数:circlenum = Math.min((m+1)/2, (n+1)/2);
2. 对于给定的一圈,从按顺序进行遍历:遍历最上边一行,最右边一行,最下面一行,最左边一行;
如左图所示,先遍历最外边一圈,在遍历里面的一圈。
【java代码】
1 public class Solution { 2 public List<Integer> spiralOrder(int[][] matrix) { 3 List<Integer> list = new ArrayList<Integer>(); 4 if(matrix == null || matrix.length == 0) return list; 5 //确定需要遍历的圈数 6 int circlenum = Math.min((matrix.length+1)/2, (matrix[0].length+1)/2); 7 //对每一圈进行序列化 8 for(int i = 0; i < circlenum; i++){ 9 getOutCircle(list, matrix, i); 10 } 11 12 return list; 13 } 14 15 public void getOutCircle(List<Integer> list, int[][] matrix, int num){ 16 int rownum = matrix.length - num*2; //确定这一圈的行数 17 int colnum = matrix[0].length - num*2; //确定这一圈的列数 18 19 for(int j = 0; j < colnum; j++) list.add(matrix[num][num+j]); 20 if(rownum <= 1) return; //如果只有一行 21 for(int i = 1; i < rownum; i++) list.add(matrix[num + i][num+colnum-1]); 22 if(colnum <= 1) return; //如果只有一列 23 for(int j = 1; j < colnum; j++) list.add(matrix[num+rownum-1][num+colnum-j-1]); 24 for(int i = 1; i < rownum - 1; i++) list.add(matrix[num+rownum-1-i][num]); 25 } 26 }
上面代码虽然可以解决问题,但是可读性不强,而且通过圈来对矩阵进行遍历,一些下标控制会让大家很懵逼,下面是一个简单的版本,很容易理解。
1 public class Solution { 2 public List<Integer> spiralOrder(int[][] matrix) { 3 List<Integer> res = new ArrayList<Integer>(); 4 if(matrix.length == 0 || matrix[0].length == 0) return res; 5 6 int top = 0; 7 int bottom = matrix.length-1; 8 int left = 0; 9 int right = matrix[0].length-1; 10 11 while(true){ 12 for(int i = left; i <= right; i++) res.add(matrix[top][i]); 13 top++; 14 if(left > right || top > bottom) break; 15 16 for(int i = top; i <= bottom; i++) res.add(matrix[i][right]); 17 right--; 18 if(left > right || top > bottom) break; 19 20 for(int i = right; i >= left; i--) res.add(matrix[bottom][i]); 21 bottom--; 22 if(left > right || top > bottom) break; 23 24 for(int i = bottom; i >= top; i--) res.add(matrix[i][left]); 25 left++; 26 if(left > right || top > bottom) break; 27 } 28 29 return res; 30 } 31 }