剑指offer面试题29:顺时针打印矩阵(Java 实现)

题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
1   2    3    45   6    7    89  10  11  1213 14  15  16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

思路:

可以把矩阵看成是由外圈内圈这样一圈圈组成的,打印第一圈的左上角坐标为(0,0),打印第二圈的左上角坐标为(2,2),依次类推为(start,start)。

然后我们可以构造一个函数来打印最外圈的的数字,然后内圈可以用递归的方式进行打印。

在调用递归函数进行循环打印要注意循环继续打印的条件为:每一次都要保证矩阵的行数和列数大于两倍的起始坐标的行坐标或者列坐标(matrix.length>start2 && matrix[0].length>start2)。

测试用例:

  1. 功能测试:数组中有多行多列。
  2. 特殊测试:数组中只有一行或一列;数组中只有一个数字(一行一列)。
  3. 负面测试:输入的数组为空。
public class test_twenty_night {
    public ArrayList<Integer> printMatrix(int[][] matrix){
        ArrayList<Integer> list = new ArrayList<>();

        if(matrix == null)return list;

        int start = 0;
        
        while(matrix[0].length>start*2 && matrix.length>start*2){
            printOneCircle(matrix, start, list);
            start++;
        }
        return list;
    }

    //构造一个函数打印矩阵最外面一圈
    private void printOneCircle(int[][] matrix, int start, ArrayList<Integer> list) {
    
        int endX = matrix[0].length - 1 - start;      //列
        int endY = matrix.length - 1 - start;         //行

        //从左到右打印
        for(int i = start; i<=endX; i++){
            list.add(matrix[start][i]);
        }

        //从上到下打印
        if(start < endY){
            for (int i = start+1; i<= endY; i++){
                list.add(matrix[i][endX]);
            }
        }

        //从右到左打印(需要判断是否跟之前从左到右是同一行重复打印)
        if(start<endX && start<endY){
            for (int i = endX-1; i>=start; i--){
                list.add(matrix[endY][i]);
            }
        }

        //从下到上打印(需要判断是否跟之前从上到下是同一列重复打印)
        if (start<endX && start<endY-1){
            for (int i = endY-1; i>=start+1; i--){
                list.add(matrix[i][start]);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41163113/article/details/86536427