题目: 给你一个正整数 n
,生成一个包含 1
到
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
思路: 在解决这个问题时,可以从以下几个方面入手思考:
**确定填充顺序:**了解如何按照顺时针的顺序填入数字是解决问题的关键。通常可以按照从左到右、从上到下、从右到左、从下到上的顺序进行填充。这一点是解决问题的基础。
**确定边界条件:**确定每一轮填充数字时的边界条件至关重要。边界条件包括上边界、下边界、左边界和右边界,它们在每一轮填充数字时都会发生变化。理解如何更新边界条件是解决问题的关键。
**设计填充逻辑:**设计好每一轮填充数字的逻辑是解决问题的关键。在每一轮中,需要明确从哪个方向开始填充、填充的终止条件以及如何更新边界。这一点需要细致的思考和设计。
**处理特殊情况:**在实现填充逻辑时,需要考虑各种特殊情况,例如矩阵的大小为奇数或偶数时的区别,以及最后剩下一行或一列的情况等。
**边界条件的处理:**在实现填充逻辑时,需要确保边界条件的处理是正确的,以避免越界或重复填充的情况发生。
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 初始化矩阵并填充 0
vector<vector<int>> matrix(n, vector<int>(n, 0));
int top = 0, bottom = n - 1; // 上边界和下边界
int left = 0, right = n - 1; // 左边界和右边界
int num = 1; // 要填入的数字
// 依次填入数字,直到填满整个矩阵
while (top <= bottom && left <= right) {
// 从左到右填入数字
for (int j = left; j <= right; ++j) {
matrix[top][j] = num++;
}
top++; // 上边界向下收缩
// 从上到下填入数字
for (int i = top; i <= bottom; ++i) {
matrix[i][right] = num++;
}
right--; // 右边界向左收缩
// 从右到左填入数字
for (int j = right; j >= left; --j) {
matrix[bottom][j] = num++;
}
bottom--; // 下边界向上收缩
// 从下到上填入数字
for (int i = bottom; i >= top; --i) {
matrix[i][left] = num++;
}
left++; // 左边界向右收缩
}
return matrix;
}
};
别人的另外一种写法,但思路大差不差,只是循环用的不一样。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 创建一个大小为 n x n 的二维向量,初始化为 0
vector<vector<int>> matrix(n, vector<int>(n));
int i = 0, j = -1; // 初始化行和列的索引
int len = n; // 当前需要填充的行或列的长度
int cnt = 0; // 要填充的数字,从 1 开始
int x1, y1, x2, y2; // 边界坐标
// 迭代填充数字,直到 len 为 0
while (len > 0) {
x1 = i; y1 = j + 1; x2 = i + len - 1; y2 = j + len; // 更新边界坐标
// 填充右边界
while (j + 1 <= y2)
matrix[i][++j] = ++cnt;
// 填充下边界
while (i + 1 <= x2)
matrix[++i][j] = ++cnt;
// 填充左边界
while (j - 1 >= y1)
matrix[i][--j] = ++cnt;
// 填充上边界
while (i - 1 >= x1 + 1)
matrix[--i][j] = ++cnt;
len -= 2; // 更新 len,每次填充完一个轮回,两个边界被缩小 1
}
return matrix; // 返回填充好的矩阵
}
};
想了解的更加仔细地话,请参考b站-代码随想录。
谢谢大家,继续努力。