模拟
模拟顺时针画矩阵过程
- 填充上行,从左到右
- 填充右列,从上到下
- 填充下行,从右到左
- 填充左列,从下到上
画一圈需要画四条边,需要注意的是每画一条边都需要遵循「左闭右开」原则
,也就是说每一条边的画法要相同,不然代码会越写越乱。
下面按照左闭右开原则画一圈:
每一种颜色代表一条边,在拐角处画新的边。
class Solution {
public int[][] generateMatrix(int n) {
// 定义一个二维数组
int[][] ans = new int[n][n];
// 定义每循环一个圈的起始位置
int startX = 0, startY = 0;
// 每个圈循环几次
int loop = n/2;
// 矩阵中间位置
int mid = n/2;
// 用来给矩阵中每一个空格赋值
int count = 1;
// 每循环一圈需要控制每一条边的遍历长度
int offset = 1;
int i, j;
while (loop-- > 0) {
// 模拟填充上行,从左到右(左闭右开)
for (j = startY; j < startY + n - offset; j++) {
ans[startX][j] = count++;
}
for (i = startX; i < startX + n - offset; i++) {
ans[i][j] = count++;
}
for (; j > startY; j--) {
ans[i][j] = count++;
}
for (; i > startX; i--) {
ans[i][j] = count++;
}
// 第二圈开始后起始位置各自加1
startX++;
startY++;
// 控制每一条边的遍历长度
offset+=2;
}
// 如果n为奇数,则需要单独为中间位置赋值
if (n % 2 != 0) {
ans[mid][mid] = count;
}
return ans;
}
}
剑指offer第29题相同解法
剑指offer第29题 顺时针打印矩阵
按层模拟
class Solution {
public int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
int counter = 1;
int left = 0, top = 0, right = n - 1, bottom = n- 1;
while (left <= right && top <= bottom) {
for (int i = left; i <= right; i++) {
ans[top][i] = counter++;
}
for (int i = top + 1; i <= bottom; i++) {
ans[i][right] = counter++;
}
if (left < right && top < bottom) {
for (int i = right - 1; i >= left; i--) {
ans[bottom][i] = counter++;
}
for (int i = bottom - 1; i > top; i--) {
ans[i][left] = counter++;
}
}
left++;
top++;
right--;
bottom--;
}
return ans;
}
}
使用辅助数组模拟
class Solution {
public int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
int counter = 1;
boolean[][] visited = new boolean[n][n];
int[][] dirs = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int row = 0, col = 0, dirIdx = 0;
for (int i = 0; i < n * n; i++) {
ans[row][col] = counter++;
visited[row][col] = true;
int[] dir = dirs[dirIdx];
int nextRow = row + dir[0];
int nextCol = col + dir[1];
if (nextRow >= n || nextRow < 0 || nextCol >= n || nextCol < 0 || visited[nextRow][nextCol]) {
dirIdx = (dirIdx + 1) % 4;
}
row += dirs[dirIdx][0];
col += dirs[dirIdx][1];
}
return ans;
}
}