开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
Day32 2023/02/07
难度:简单
题目
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
思路一
本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力 ,我们只要可以用代码模拟出画全的过程即可。
具体步骤
- 从左到右填充上行
- 从上到下填充右列
- 从右到左填充下行
- 从下到上填充左列
关键点
- 每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
算法实现
c++代码实现-过程模拟
class Solution {
public:
// 返回类型为一个二维数组
vector<vector<int>> generateMatrix(int n) {
// vector<int> res(len,
// element);其中第一个参数为指定数组长度,第二个元素指定每个元素的初值
vector<vector<int>> res(n, vector<int>(n, 0)); //使用vector定义一个二维数组
int startx = 0, starty = 0; //定义每圈循环的起始位置(startx,starty)
int loop = n / 2; //生成一个按顺时针顺序螺旋排列的n*n的的正方形矩阵,需要循环的圈数
//,列入n=2,则loop=1,只需要循环一圈就可以得到该矩阵
int mid = n / 2; //当n为奇数时矩阵的中心位置
int count = 1; //用来给矩阵中每一个元素赋值
int offset = 1; //需要控制不同圈中每一条边遍历的长度,即每次循环有边界都要收缩一位(n
//- offset)
int i, j;
while (loop--) {
//下面的4个for循环就是模拟螺旋排列一圈
//从起始位置(startx,starty)开始,模拟上行自左向右,并且遵循循环不变量(边界按照左闭右开)
for (j = starty; j < n - offset;
j++) { //遍历元素即第一行第一个元素到倒数第二个(右开)
res[startx][j] = count++;
}
//从位置(startx,n-offset-1)开始,模拟右列从自上向下,并且遵循循环不变量(边界按照左闭右开)
for (i = startx; i < n - offset; i++) {
res[i][j] = count++;
}
//从位置(n-offset-1,j)开始,模拟下行从自右向左,并且遵循循环不变量(边界按照左闭右开)
for (; j > starty; j--) { //这是j = i = n - offset -1
res[i][j] = count++;
}
//从位置(n-offset-1,
//starty)开始,模拟左列从自下向上,并且遵循循环不变量(边界按照左闭右开)
for (; i > startx; i--) {
res[i][j] = count++;
}
//从第二圈开始,起始位置发生改变,各自加一,例如第一圈为(0,0),第二圈为(1,1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
//如果n为奇数的话,中间元素需要单独处理(单独赋值)
if (n % 2 == 1)
res[mid][mid] = count;
return res;
}
};
总结
可以看出while循环里判断的情况是很多的,代码里处理的原则也是统一的左闭右开,这样便于边界条件的判定。