搞了半天,细节有点复杂!
问题描述
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。大概就是下图这个效果。
思路分析
本题的思路比较多,比较杂;但是主体的思路为模拟其真实过程。
方法一:
随想录中给出了一种清晰的方法,将全过程拆分成多个相同的小过程。其思路为:
将螺旋矩阵层层拆分,对于每一层都可以采用相同的方法。那首先分析最外层,最外层的元素一共有4(n-1)个,那就可再分成4步,一步生成n-1个,也就是4条边各n-1个元素。按照上、右、下、左的顺序,就可以逐层生成下去。
那对于最里层呢?这里就需要分析一下奇、偶了。每一层会相对其外层少两个元素,到了最里层会出现两种情况:
- 四个元素:即我们上、右、下、左各一个元素,这一层每个方向都是一个元素;那么反推回去就可以得到n-1为奇数,n为偶数;
- 一个元素:由上面得n为奇数,那么n为奇数时就将再新增一个中心点元素。
代码实现
class Solution {
public int[][] generateMatrix(int n) {
int offset = 0, loop = 1, num = 1;
int[][] ans = new int[n][n];
while (loop <= n/2 ) {
int i = offset, j = offset;
for (; j < n - offset- 1; j++, num++) {
ans[offset][j] = num;
}
for (; i < n - offset - 1; i++, num++) {
ans[i][n-offset-1] = num;
}
for (; j > offset; j--, num++) {
ans[n - offset - 1][j] = num;
}
for (; i > offset; i--, num++) {
ans[i][offset] = num;
}
loop++;
offset++;
}
if (n%2 == 1) ans[n/2][n/2] = n*n;
return ans;
}
}
难点在于边界条件和上下层的转换:
- 边界条件:每一层的起始、终止,控制好区间;
- 上层到下层的转换就是前后各少一个,然后不变的指标加一。
方法二:
class Solution {
public int[][] generateMatrix(int n) {
int t = 0, b = n-1, l = 0, r = n -1, k = 1;
int[][] ans = new int[n][n];
while (k <= n*n) {
for (int i = l; i <= r; i++, k++) {
ans[t][i] = k;
}
t++;
for (int i = t; i <= b; i++, k++) {
ans[i][r] = k;
}
r--;
for (int i = r; i >= l; i--, k++) {
ans[b][i] = k;
}
b--;
for (int i = b; i >= t; i--, k++) {
ans[i][l] = k;
}
l++;
}
return ans;
}
}
该方法是看到的别人的解法,看起来工整,但是其中实现思路没有这么清晰。