59、螺旋矩阵II
题目描述
输入一个正整数n,生成从1到n2的所有元素,把这些元素从小到大按顺时针顺序螺旋排列到n * n
的正方形矩阵中。
思路
- 本题涉及到的是一个模拟过程,即 把生成的数字从小到大按顺时针顺序螺旋排列给正方形数组(模拟出围着正方形数组顺时针移动即可)。
- 在模拟过程中分两种情况——n为偶数、n为奇数
1. n为偶数: 这种情况下,正常的进行顺时针模拟就可以把所有元素放入矩阵中。
2. **n为奇数:**在这种情况下,最终会有最中间的一个格子不能被赋值。这是,我们要做的就是推导出计算中间坐标的公式:mid=n/2
代码
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0)); //使用vector定义一个二维数组
int startx = 0, starty = 0;//定义每次顺时针模拟的起始位置
int loop = n / 2;//需要模拟顺时针循环赋值的次数
int mid = n / 2;//n为奇数时,中间坐标的位置
int num = 1;//用来给矩阵赋值,范围在[1,n*n]
int offset = 1;//用来控制每条边遍历的长度。每顺时针循环一次,遍历的的长度就减小1
int i, j;
while (loop--) {
i = startx;//横坐标
j = starty;//纵坐标
//下面四个for循环模拟顺时针螺旋一圈
//模拟填充正方形上面的一行,从左到右
for (j; j < n - offset; j++ ) {
res[i][j] = num++;
}
//模拟填充正方形右面的一列,从上到下
for (i; i < n - offset; i++) {
res[i][j] = num++;
}
//模拟填充正方形下面的一列,从右到左
for (j; j > starty; j--) {
res[i][j] = num++;
}
//模拟填充正方形左面的一列,从下到上
for (i; i > startx; i--) {
res[i][j] = num++;
}
//每模拟完成依次正方形的顺时针循环后,起始位置都要各自加1.【第一次顺时针循环的起始位置是(0,0),第二次顺时针循环的起始位置是(1,1)】
startx++;
starty++;
//每顺时针循环完一次,下一次顺时针循环中每条边遍历的长度减一(offset++)
offset++;
}
//如果n为奇数,需要单独算出矩阵中间位置的坐标
if (n % 2) {
res[mid][mid] = num;
}
return res;
}
};
时间复杂度:O(n2)
空间复杂度:O(n2)