【数组】剑指 Offer 29. 顺时针打印矩阵
题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
解答:
方法一:将顺时针打印矩阵变为打印多个圆环的小问题。

把矩阵看成由若干个顺时针方向的圈组成。将矩阵从最外圈开始,一圈一圈的输出。一般打印外层的圈需要分四步:从左到右,从上到下,从右到左,从下到上。
而对于最后一圈有可能退化成只有一行、只有一列,甚至只有一个数字。打印最后一圈需要的分开来讨论。有三种情况。

时间复杂度:O(MN),M,N分别为矩阵的行数和列数。
空间复杂度:O (MN)
class Solution { public int index = 0; public int[] spiralOrder(int[][] matrix) { if(matrix.length == 0) return (new int[0]); int rows = matrix.length, columns = matrix[0].length; int[] res = new int[rows*columns]; int start = 0; while(columns > start*2 && rows > start*2){ spiral(res,matrix,start); start++; } return res; } public void spiral(int[] res,int[][] matrix,int start){ int rows = matrix.length, columns = matrix[0].length; int endX = columns - 1 - start; int endY = rows - 1 - start;
//从左到右 for(int i = start;i<=endX;i++){ res[index] = matrix[start][i]; index++; }
//从上到下 if(start<endY){ for(int i = start+1;i<=endY;i++){ res[index] = matrix[i][endX]; index++; } }
//从右到左
if(start<endX && start<endY){ for(int i = endX-1;i>=start;i--){ res[index] = matrix[endY][i]; index++; } }
//从下到上 if(start<endX && start<endY-1){ for(int i = endY-1;i>=start+1;i--){ res[index] = matrix[i][start]; index++; } } } }
方法二:“从左向右、从上向下、从右向左、从下向上” 循环。(leecode用户题解)

class Solution { public int[] spiralOrder(int[][] matrix) { if(matrix.length == 0) return new int[0]; int left = 0, right = matrix[0].length-1,top = 0, bottom = matrix.length-1,x = 0; int res[] = new int[matrix.length * matrix[0].length]; while(true){ for(int i=left;i<=right;i++){ res[x++] = matrix[top][i]; } if(++top > bottom) break; for(int i = top;i<=bottom;i++){ res[x++] = matrix[i][right]; } if(--right<left) break; for(int i = right;i>=left;i--){ res[x++] = matrix[bottom][i]; } if(--bottom<top) break; for(int i = bottom;i>=top;i--){ res[x++] = matrix[i][left]; } if(++left>right) break; } return res; } }

浙公网安备 33010602011771号