力扣59. 螺旋矩阵 II
题目来源(力扣):
https://leetcode.cn/problems/spiral-matrix-ii/description/
题目描述:
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
基本思路:
经典模拟,考察对二维数组下标维护和更新的基本能力。
难点主要是如何和巧妙地更新x,y下标的值,实际上动动手模拟一下n=6(甚至更大)时的情况,就会发现实际上每次填数无非是进行
右、下、左、上的循环,而且每次循环的移动次数依次为5、3、1。
再注意到,n为奇数与n为偶数时有一点点不同,例如n=5,每次循环的移动次数就依次为4、2、0,这个“0”实际上就是数组正中间的数字为n*n。
因此,对于n为偶数的数组,直接填数,对于n为奇数的数组特殊判断一下下即可。
《代码随想录》中写法较为复杂,我在这里进行了改进,如下:
代码实现:
class Solution
{
public:
vector<vector<int>> generateMatrix(int n)
{
vector<vector<int>> ans(n, vector(n, 0));
int tot = 1; // 即将填写的数
int x = 0, y = 0;
int k = n - 1; //每次循环时,上、右、下、左移动k步
while (k > 0)
{
// right
for (int i = 0; i < k; i++)
ans[x][y++] = tot++;
// down
for (int i = 0; i < k; i++)
ans[x++][y] = tot++;
// left
for (int i = 0; i < k; i++)
ans[x][y--] = tot++;
// up
for (int i = 0; i < k; i++)
ans[x--][y] = tot++;
// 对up后的位置进行纠正 而right down left不需要纠正,是因为“它们的终点就是下一个起点”,例如“right的终点就是down的起点”。可以结合n=5来手动推一下
x++, y++;
// 更新k
k -= 2;
}
if (n & 1)
ans[n / 2][n / 2] = n * n;
return ans;
}
};
时间复杂度
O(n*n) n为矩阵的边长
浙公网安备 33010602011771号