给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
一般可以分为两种情况,n = 奇数,n = 偶数;
当n = 奇数(3)和 n = 偶数(4)不同之处在于,
- n为偶数时,循环完恰好组成了螺旋矩阵
- n为奇数时,循环结束,需要在中心填充最后的值!
还有一点需要注意的是,循环次数要根据输入的n来定!
- n = 1时,不需要循环,直接在最后的中心填充值为1!
- n = 3时,需要循环1次,然后在最后的中心填充值为9;
- n = 4时,需要循环2次,不需要对中心进行填充就直接完成了螺旋数组的构建
此外:填充时候要遵循左闭右开。把每一行(列)的最后一个元素留给下一列(行)来处理。
先放上绘制 n = 3 的代码:
没有外层循环,只循环一次便可绘制成功
package array;
import java.util.Arrays;
public class GenerateMatrix {
public static void main(String[] args) {
int[][] ints = generateMatrix(3);
for (int[] anInt : ints) {
System.out.println(Arrays.toString(anInt));
}
}
public static int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
int num = 1;
int start = 0;
int i;
int j;
// 绘制最上边的横线
for (i = 0; i < n - 1; i++) {
result[start][i] = num;
num++;
}
// 绘制最右边的竖线
for (j = 0; j < n - 1; j++) {
result[j][n - 1] = num;
num++;
}
// 绘制最下边的横线
for(; i > 0; i--) {
result[n - 1][i] = num;
num++;
}
// 绘制最右边的竖线
for (; j > 0; j--) {
result[j][i] = num;
num++;
}
// 如果n = 奇数
if (n % 2 == 1) {
// 最中间填充
result[n % 2][n % 2] = num;
}
return result;
}
}
结果
完整代码,需要在绘制n = 3的基础上再加一层for循环即可!用来控制循环次数
我们可以发现
- n = 1时不用进行循环;
- n = 2时循环一次不用填充
- n = 3时循环一次,最后中心填充
- n = 4时循环二次不用填充
所以最外层的循环次数与n有关,关系为:
注意
- 外层循环次数使用iteration,并且iteration也用来控制内层循环的次数
- 数据开始填充的位置--使用变量start控制
- 注意与上文n = 3(一次循环)的区别!对比来看理解更加透彻
最后看代码时候一定要注意代码中的注释和解析!
package array;
import java.util.Arrays;
public class GenerateMatrix {
public static void main(String[] args) {
int[][] ints = generateMatrix(4);
for (int[] anInt : ints) {
System.out.println(Arrays.toString(anInt));
}
}
public static int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
// 用来控制数字填充
int num = 1;
// 用来控制填充的层数
int start = 0;
// 用来控制填充的位置。也就是 可以说是循环的每一圈,最开始的位置坐标是start
int i;
int j;
// 控制循环次数
int iteration = 0;
while (iteration++ < n / 2){
// 绘制最上边的横线
for (i = start; i < n - iteration; i++) {
result[start][i] = num;
num++;
}
// 绘制最右边的竖线
for (j = start; j < n - iteration; j++) {
result[j][i] = num;
num++;
}
// 绘制最下边的横线
for(; i >= iteration; i--) {
result[j][i] = num;
num++;
}
for (; j >= iteration; j--) {
result[j][i] = num;
num++;
}
start++;
}
// 如果n = 奇数
if (n % 2 == 1) {
// 最中间填充
result[start][start] = num;
}
return result;
}
}