剑指offer第二版-29.顺时针打印矩阵

本系列导航:剑指offer(第二版)java实现导航帖

面试题29:顺时针打印矩阵

题目要求:
输入一个矩阵,按照从外向里以顺时针的顺序一次打印出每一个数字。
如果输入如下矩阵:

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。

解题思路:
此题的任务清晰明了,需要小心的是要考虑清楚边界情况。
上例中,环绕一次后,剩下的矩阵行数为2,列数为2,可以看成一个新的矩阵,继续环绕打印。可见,此题可以用递归解决。
示例中行数与列数是相等的,所以能够组成完整的环(完整指能够环绕一圈);其实,只要行数和列数中,比较小的那个是偶数,就能够组成完整的环。
如果行数和列数中比较小的那个是奇数,则递归到终止前的剩余元素无法成环。如果较小的是行数,则剩余元素的组成的形状类似于“|”;如果较小的是列数,则剩余元素的组成的形状类似于“—”。
因此,当未访问行数和未访问列数都大于等于2时,按照完整环的逻辑递归访问即可。当不满足上述条件,判断剩余元素是“|”型还是“—”型,然后按照不完整环的逻辑访问即可。

package chapter4;

/**
 * Created by ryder on 2017/7/16.
 *
 */
public class P161_PrintMatrix {
    public static void printMatrix(int[][] data){
        if(data==null)
            return ;
        if(data.length==0||data[0].length==0)
            return ;
        int rowMax = data.length-1,rowLen = data.length;
        int colMax =data[0].length-1,colLen = data[0].length;
        int row=0,col=0,round=0;
        while(rowLen-2*row>1 && colLen-2*col>1){
            for(;col<=colMax-round;col++){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            for(col=col-1,row=row+1;row<rowMax-round;row++){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            for(;col>=round;col--){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            for(col=col+1,row=row-1;row>round;row--){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            row=row+1;
            col=col+1;
            round++;
        }
        //如果行数与列数中较小的那个是偶数,则能组成完整的环,在while中就完成了遍历
        if(rowLen-2*row==0 || colLen-2*col==0){
            System.out.println();
        }
        //如果行数与列数中较小的是行数,且是奇数,则还需补充访问一行
        if(rowLen-2*row==1){
            for(;col<=colMax-round;col++){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            System.out.println();
        }
        //如果行数与列数中较小的是列数,且是奇数,则还需补充访问一列
        if(colLen-2*col==1){
            for(;row<=rowMax-round;row++){
                System.out.print(data[row][col]);
                System.out.print("\t");
            }
            System.out.println();
        }

    }
    public static void main(String[] args){
        int[][] data1={
                {1,2,3,4},
                {12,13,14,5},
                {11,16,15,6},
                {10,9,8,7},
        };
        int[][] data2={
                {1,2,3,4},
                {10,11,12,5},
                {9,8,7,6},
        };
        int[][] data3={
                {1,2,3},
                {10,11,4},
                {9,12,5},
                {8,7,6},
        };
        int[][] data4={
                {1,2,3},
                {8,9,4},
                {7,6,5},
        };
        printMatrix(data1);
        printMatrix(data2);
        printMatrix(data3);
        printMatrix(data4);
    }
}

运行结果

1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  
1   2   3   4   5   6   7   8   9   10  11  12  
1   2   3   4   5   6   7   8   9   10  11  12  
1   2   3   4   5   6   7   8   9   

推荐阅读更多精彩内容