由外向里顺时针打印矩阵元素

来源:互联网 发布:c 最小公倍数算法 编辑:程序博客网 时间:2024/05/09 02:44

原本只是实现下面 1 这个问题,扩展问题并得到问题 2 的实现思路,最后发现剑指offer上有一道经典的顺时针打印矩阵元素的题目,基于问题 2 的编程思路给出了剑指offer上这道题自己的实现。

1、给定一个正整数n,输出一个n*n的矩阵,矩阵的元素由外向内以顺时针方向从1开始递增
输入输出示例如下:

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

代码实现:

private static void printLoopMatrix(int n) {        if(n <= 0)             throw new IllegalArgumentException("n must be a positive number");        int arr[][] = new int[n][n];        int minX = 0, maxX = n - 1, minY = 0, maxY = n - 1;        int x = 0, y = 0;        int val = 1;        while(minX <= maxX && minY <= maxY) {            //左→右            while(y < maxY)                 arr[x][y++] = val++;            minX++;            //上→下            while(x < maxX)                 arr[x++][y] = val++;            maxY--;            //右→左            while(y > minY)                arr[x][y--] = val++;            maxX--;            //下→上            while(x > minX)                 arr[x--][y] = val++;                minY++;         }        arr[x][y] = val;        System.out.println(Arrays.deepToString(arr));    }  

2、对上面这个题目进行扩展,如果给定m和n,按 1 中的要求生成一个m*n的矩阵,输入输出示例如下:

Input:3 5
Output: 1   2   3   4   5
                12 13 14 15 6
                11 10 9   8   7

代码实现:

private static void printLoopMatrix(int m, int n) {        if(m <= 0 || n <= 0)             throw new IllegalArgumentException("m or n is not positive");        int arr[][] = new int[m][n];        int minX = 0, maxX = m - 1, minY = 0, maxY = n - 1;        int x = 0, y = 0;        int val = 1;        while(minX <= maxX && minY <= maxY) {            //左→右            while(y < maxY)                 arr[x][y++] = val++;            minX++;            //上→下            while(x < maxX)                 arr[x++][y] = val++;            maxY--;            //右→左            while(y > minY && x >= minX) //              System.out.println(x +" " + minX);                arr[x][y--] = val++;            maxX--;            //下→上            while(x > minX && y <= maxY)                 arr[x--][y] = val++;                minY++;         }        arr[x][y] = val;        System.out.println(Arrays.deepToString(arr));    }

下面基于上面两个小练习得出一种按顺时针打印矩阵元素的思路
3、给定一个矩阵,按顺时针方向由外向里打印矩阵元素。
输入输出示例如下:

Input:1   2   3   4   5
            12 13 14 15 6
            11 10 9   8   7
Output:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

代码实现:

private static void printMatrixClockWise(int[][] matrix) {        if (matrix == null)            throw new IllegalArgumentException("matrix is null");        if (matrix.length == 0 || matrix[0].length == 0)            throw new IllegalArgumentException("matrix dimension is zero");        int minX = 0, maxX = matrix.length - 1, minY = 0, maxY = matrix[0].length - 1;        int x = 0, y = 0;        while(minX <= maxX && minY <= maxY) {            // 左→右            while(y < maxY)                 System.out.printf("%d ", matrix[x][y++]);            minX++;            // 上→下            while(x < maxX)                 System.out.printf("%d ", matrix[x++][y]);            maxY--;            // 右→左            while(y > minY && x >= minX)                System.out.printf("%d ", matrix[x][y--]);            maxX--;            // 下→上            while(x > minX && y <= maxY)                System.out.printf("%d ", matrix[x--][y]);            minY++;         }        System.out.printf("%d\n", matrix[x][y]);    }

这是剑指offer上的一道题目,给出网上最常见的代码实现: (这个实现参考于http://blog.csdn.net/yanxiaolx/article/details/52254590,网上其他实现也是大同小异)

private static void printMatrixClockWise2(int matrix[][]){        if (matrix == null)            throw new IllegalArgumentException("matrix is null");        if (matrix.length == 0 || matrix[0].length == 0)            throw new IllegalArgumentException("matrix dimension is zero");        int rows = matrix.length;        int cols = matrix[0].length;        int start = 0;        while(rows > 2 * start && cols > 2* start) {            int endX = rows - 1 - start;            int endY = cols - 1 - start;            // 左→右            for (int i = start; i <= endY; i++) {                System.out.printf("%d ", matrix[start][i]);            }            // 上→下            if (start < endX) {                for (int i = start + 1; i <= endX; i++) {                    System.out.printf("%d ", matrix[i][endY]);                }            }            // 右→左            if (start < endX && start < endY) {                for (int i = endY - 1; i >= start; i--) {                    System.out.printf("%d ", matrix[endX][i]);                }            }            // 下→上            if (start < endX -1 && start < endY) {                for (int i = endX - 1; i > start; i--) {                    System.out.printf("%d ", matrix[i][start]);                }            }            start++;        }        System.out.println("");    }

通过比较,自己的实现比剑指offer上的实现效率要低一些,尤其是矩阵维度小的时候相差达到了一个数量级,而矩阵维度越大两种实现效率的差别反而不明显。

0 0