原本只是实现下面 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.youkuaiyun.com/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上的实现效率要低一些,尤其是矩阵维度小的时候相差达到了一个数量级,而矩阵维度越大两种实现效率的差别反而不明显。