【数组】剑指 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;
    }
}

 

posted @ 2020-09-12 23:16  3KBLACK  阅读(95)  评论(0)    收藏  举报