题目
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例
输入:n = 3 解释: |
输入:n = 1 输出:[[1]] |
思路
这道题不需要用到任何算法,但是做这道题前我们需要解决几个问题:
1. 这个螺旋矩阵要转几圈?
2. 每条边怎么去填入数字?
3. 对于奇数边长无法通过循环填充的中心点,应该怎么办?
在不考虑奇数边长中心点的前提下,第一个问题的答案是n/2(n是输入的边长)。第一次转一圈每边的边长就是n,而下一次的螺旋的边长就变成了n-2,因为对于每条边来说,两端的空格都已经被填满了,不需要再次填充。以此类推,螺旋矩阵要转几圈的问题就变成了n可以减几次2,答案也就显而易见,是n/2的取整了。
在填充的过程中,我们希望每条边都是有规律的去填充,而不是第一条边填充3个,第二条边填充四个这样。因此我们规定在填充每条边时都遵循左闭右开的原则,下面这张图或许能够帮助理解:
第三个问题,其实非常简单。我们只需要在循环外加一个if条件去判断是不是奇数边即可。如果是奇数边,找到中心位置填充剩余的数字即可。
代码实现
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数
int[][] result = new int[n][n];
int start = 0; // 每次循环的开始点(start, start)
int count = 1; // 定义填充数字
int i, j;
while(loop++ < n/2){
for(j = start; j < n - loop; j++){ //从左到右
result[start][j] = count++;
}
for(i = start; i < n - loop; i++){ //从上到下
result[i][j] = count++;
}
for(; j >= loop; j--){ //从右到左
result[i][j] = count++;
}
for(; i >= loop; i--){ //从下到上
result[i][j] = count++;
}
start++; //改变每次转圈的起始点
}
if(n%2 == 1){
result[start][start] = count;
}
return result;
}
}
这里我们每一次循环都遵循从左到右,从上到下,再从右到左,最后从下到上的顺序。