给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
本题不涉及算法,就是模拟过程,但却十分考察对代码的掌控能力。
C代码:模拟
(1)统一使用:memset(arr[i], 0, sizeof(int)*n);
memset(arr[i], 0, sizeof(arr[i])) 就报错!
返回结果:[[1,2,-1094795586],[6,7,-1094795586],[9,8,-1094795586]]
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
int** arr = (int *)malloc(sizeof(int *) * n); // 提前分配内存,在返回时就不会指向NULL
for (int i = 0; i < n; ++i) {
arr[i] = malloc(sizeof(int) *n);
memset(arr[i], 0, sizeof(int)*n); // memset(arr[i], 0, sizeof(arr[i])) 就报错!
}
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 方向
int idx = 0;
int row = 0, col = 0;
for (int i = 1; i <= n * n; ++i) {
arr[row][col] = i;
int nextRow = row + directions[idx][0]; // 往 上/下/左/右 再走一步;
int nextCol = col + directions[idx][1];
if (nextRow >= n || nextRow < 0 || nextCol >= n || nextCol < 0 || arr[nextRow][nextCol] != 0) {
idx = (idx + 1) % 4; // 走出边界 or 下一步存在值:就换方向!
}
row = row + directions[idx][0]; // idx:0 1 2 3
col = row + directions[idx][1]; // 往 上/下/左/右 再走一步;
}
*returnSize = n;
*returnColumnSizes = malloc(sizeof(int) * n);
for (int i = 0; i < n; ++i) {
(*returnColumnSizes)[i] = n; // 每行均有n列
}
return arr;
}
Java代码1:模拟
public int[][] generateMatrix(int n) {
int rows = n, cols = n;
int total = n * n;
int[][] matrix = new int[n][n];
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int directionIdx = 0;
int row = 0, col = 0;
int cnt = 1;
while (cnt <= total) {
matrix[row][col] = cnt;
++cnt;
int nextRow = row + directions[directionIdx][0];
int nextCol = col + directions[directionIdx][1];
if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols || matrix[nextRow][nextCol] != 0) {
directionIdx = (directionIdx + 1) % 4; //visited[nextRow][nextCol]
}
row += directions[directionIdx][0];
col += directions[directionIdx][1];
}
return matrix;
}
Java代码2:按层模拟
public int[][] generateMatrix(int n) {
int left = 0, right = n - 1, top = 0, bottom = n - 1;
int[][] ans = new int[n][n];
int count = 1;
while (left < right && top < bottom) {
int i = top; //遍历行
int j = left; //遍历列
for (; j < right; ++j) ans[top][j] = count++; //列从左到右
for (; i < bottom; ++i) ans[i][right] = count++;
for (; j > left; --j) ans[bottom][j] = count++;
for (; i > top; --i) ans[i][left] = count++;
++left;
++top;
--right;
--bottom;
}
if (n % 2 == 1) ans[n / 2][n / 2] = count; // 此算法仅针对正方形,长方形不好使
return ans;
}