0
点赞
收藏
分享

微信扫一扫

60、【数组】leetcode——[ 高频考题 ]59. 螺旋矩阵 II(C++、Python版本)

我阿霆哥 2022-02-19 阅读 30

1. 题目描述

在这里插入图片描述
在这里插入图片描述
运行效果
image.png
图示举例
image.png

2. 方法一:以起点、长度为研究对象,迭代更新

观察矩阵特点,填充顺序是从左至右、从上至下、从右至左、从下至上,然后再次在新的起点进行相同顺序填充。可发现每次新填充的起点沿着矩阵的主对角线。
在这一个过程中有三个重要的地方:填充起点、填充顺序和填充长度。

由此,构建仿真模拟这一过程。

  1. 填充起点设置对角线,每填充新的一层就往对角线下移动一个位置。
  2. 填充顺序按照右、下、左、上顺序进行。
  3. 填充长度设置一个偏移量,来控制每层填充的长度。以左闭右开([,))的填充方式进行填充。即一个方向上只填充n-1个数。

C++版本

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n));     
        if(n == 1) { res[0][0] = 1;      return res;}   // 若为1则直接返回

        int startx = 0, starty = 0;     // 设置每轮起点
        int loop = n / 2;               // 设置填充层数
        int mid = n / 2;                // 若n为奇数,则需要单独多填充一块
        int count = 1;                  // 计数
        int offset = 1;                 // 控制填充长度的偏移量
        int i,j;

        while(loop--){
            i = startx;                 // 每层开始更新起点
            j = starty;

            for(; j < n - offset; j++){    // 向右,starty + n - offset控制填充长度
                res[i][j] = count++;
            }

            for(; i < n - offset; i++){    // 向下
                res[i][j] = count++;
            }

            for(; j > starty; j--){                 // 向左,若偏移起点,则按顺序进行向左填充
                res[i][j] = count++;
            }

            for(; i > startx; i--){                 // 向上,若偏移起点,则按顺序进行向右填充
                res[i][j] = count++;
            }

            startx++;                 // 更新起点
            starty++;
            offset += 1;              // 更新偏移量
        }

        if(n % 2)   res[mid][mid] = count;  // 若n为奇数,则需要单独填充一块
        return res;


    }

};


Python版本

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        res = [[0]*n for _ in range(n)]
        startx, starty, loop, mid = 0, 0, n // 2, n // 2
        count = 1

        for offset in range(1, loop + 1):               # 每循环一层偏移量加1
            for j in range(starty, n - offset):         # 从左走至右
                res[startx][j] = count
                count += 1

            for i in range(startx, n - offset):         # 从上走至下
                res[i][n - offset] = count
                count += 1

            for j in range(n - offset, starty, -1):     # 从右走至左
                res[n - offset][j] = count
                count += 1

            for i in range(n - offset, startx, -1):     # 从下走左上
                res[i][starty] = count
                count += 1
            
            startx += 1
            starty += 1
        
        if n % 2 != 0:
            res[mid][mid] = count
        return res

空间复杂度: O ( 1 ) O(1) O(1) 。除了返回的矩阵以外,空间复杂度是常数。
时间复杂度: O ( n 2 ) O(n^2) O(n2) 。 其中 nn 是给定的正整数。矩阵的大小是 n × n n \times n n×n,需要填入矩阵中的每个元素。

参考文章:
59.螺旋矩阵II

3. 方法二:边界收缩

记录矩阵的上、下、左、右边界标号,按照从左边界至右边界、从上边界至下边界、从右边界至左边界、从下边界至上边界的顺序。
每填充完一侧后,就将该测边界向内移一层,然后下一次填充就从该层边界的起始点开始填充。

C++版本

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n));

        int top = 0, buttom = n - 1, left = 0, right = n - 1;
        int count = 1, loop = n*n;

        while(loop--){
            for(int i = left; i <= right; i++)      res[top][i] = count++;      // 左边界到右边界
            top++;
            for(int i = top; i <= buttom; i++)      res[i][right] = count++;    // 上边界到下边界
            right--;
            for(int i = right; i >= left; i--)      res[buttom][i] = count++;   // 右边界到左边界
            buttom--;
            for(int i = buttom; i >= top; i--)      res[i][left] = count++;     // 下边界到上边界
            left++;
        }

        return res;
    }

};

Python版本

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        res = [[0]*n for _ in range(n)]
        left, right, top, buttom = 0, n - 1, 0, n - 1
        count, loop = 1, n*n

        for _ in range(loop):
            for i in range(left, right + 1):
                res[top][i] = count
                count += 1
            top += 1
            for i in range(top, buttom + 1):
                res[i][right] = count
                count += 1
            right -= 1
            for i in range(right, left - 1, -1):
                res[buttom][i] = count
                count += 1
            buttom -= 1
            for i in range(buttom, top - 1, -1):
                res[i][left] = count
                count += 1
            left += 1

        return res

空间复杂度: O ( 1 ) O(1) O(1) 。除了返回的矩阵以外,空间复杂度是常数。
时间复杂度: O ( n 2 ) O(n^2) O(n2) 。 其中 nn 是给定的正整数。矩阵的大小是 n × n n \times n n×n,需要填入矩阵中的每个元素。

参考文章:
Spiral Matrix II (模拟法,设定边界,代码简短清晰)

举报

相关推荐

0 条评论