思路分析
1. 确定好怎么遍历
模拟顺时针画矩阵的过程:
每遍历一完整的圈(从左到右->从上到下->从右到左->从下到上)我们要画每四条边,这四条边怎么画?
————当然要按照统一的处理规则画:【左开右闭】。
只有按左开右闭画,每一条边才能按照统一的规则画下来。(不理解自己画一遍就懂了)
2. 确定循环圈数
若n为偶数,循环 n/2 圈即可遍历完矩阵所有元素;
若n为奇数,仍是 n/2 圈。最后只剩最中间的一个元素没有遍历,直接放到后面单独赋值即可。
3. 确定每圈循环的起始位置和遍历每条边的结束位置(确立边界)
(1)第一圈循环的起始位置为(x=0,y=0),之后每圈的起始位置的x和y都要加1
(2)因为每条边是按【左闭右开】的规则画,因此每条边的结束位置不包含此边的最后一个元素,设偏移量offset为每条边结束位置的偏移量,每经过一圈offset就+1. (不懂就画n=4的矩阵理解)
参考代码
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
//定义一个二维数组并初始化为0
int startX = 0, startY = 0;
//每圈循环的起始位置为(startX,startY),每走完一圈都要+1
int loop = n / 2; //循环圈数
int mid = n / 2; //用来表示矩阵最中间的位置,为(mid,mid)
int offset = 1; //每条边结束位置的偏移量
int count = 1; //计数,给矩中每一个元素赋值
int i,j;//在外面定义为了将作用域扩大
while (loop--) {
//四个for循环就是【左闭右开】画四条边,模拟转了一圈
//画第一条边,行i不变列j变
for (j = startY; j < n - offset; j++) {
res[startX][j] = count++;
}
//画第二条边,行i变列j不变
for (i = startX; i < n - offset; i++) {
res[i][j] = count++;
}
//画第三条边,行i不变列j变
for ( ; j > startY; j--) {
res[i][j] = count++;
}
//画第四条边,行i变列j不变
for ( ; i > startX; i--) {
res[i][j] = count++;
}
//经过一圈,圈的起始位置变成(startX+1,startY+1),每条边结束位置的偏移量也+1
startX++;
startY++;
offset++;
}
//若n为奇数,单独给矩阵最中心的位置赋值
if ( n % 2 ) {
res[mid][mid] = count;
}
return res;
}
};