螺旋矩阵 II
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
- 思路
看到这道题目,可能开始没有思路,但是仔细想一想具体的过程其实就是模拟过程,模拟着画出一个螺旋矩阵即可。而在画螺旋矩阵是会遇到边界的问题。在处理边界时,一定要坚持循环不变原则,和二分法中处理边界时类似。我们这里可以采用左闭右开的原则,或是左开右闭的原则。但是不能是左闭右闭,因为这样会导致边界重复填充。
使用左闭右开原则模拟顺时针画矩阵的过程: - 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左行从下到上
这里还会遇到一个问题,当n是奇数时,最后需要单独填充最中间的一个格子。 - 代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int startx = 0,starty = 0; // 定义每循环一圈的起始位置
int loop = n / 2; // 循环多少圈,例如n = 3是奇数,那么loop = 1 ,只循环一圈,矩阵最中间的位置需要单独填充
int mid = n / 2; // 矩阵中间的位置,例如:n为3,中间的位置为(1,1),n为5,中间的位置为(2,2)
int count = 1; // 用来给矩阵中的每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
while (loop != 0){
loop --;
i = startx;
j = starty;
// 下面开始的四个for循环就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j = starty; j < n - offset; j ++) {
res[startx][j] = count++;
}
// 模拟填充右列从上到下
for (i = startx; i < n - offset; i ++) {
res[i][j] = count++;
}
// 模拟填充下行从右向左
for (; j > starty ; j--) {
res[i][j] = count++;
}
// 模拟填充左列从下到上
for (;i > startx;i --){
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1,例如:第一圈的起始位置是(0,0),第二圈的起始位置就是(1,1)。
startx ++;
starty ++;
// offset控制每一圈中买一条边遍历的长度
offset --;
}
// 如果n为奇数,需要单独给矩阵最中间的位置填充
if (n % 2 == 1){
res[mid][mid] = count;
}
return res;
}
}