力扣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为矩阵的边长

posted @ 2024-10-15 11:08  HB_Computer  阅读(16)  评论(0)    收藏  举报