数据结构与算法之深入解析“螺旋矩阵II”的求解思路与算法示例

Posted Forever_wj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法之深入解析“螺旋矩阵II”的求解思路与算法示例相关的知识,希望对你有一定的参考价值。

一、题目要求

  • 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix。
  • 示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
  • 示例 2:
输入:n = 1
输出:[[1]]

二、求解算法

① 模拟法:设定边界

  • 生成一个 n×n 空矩阵 mat,随后模拟整个向内环绕的填入过程:
    • 定义当前左右上下边界 l,r,t,b,初始值 num = 1,迭代终止值 tar = n * n;
    • 当 num <= tar 时,始终按照 从左到右 从上到下 从右到左 从下到上 填入顺序循环,每次填入后:
      • 执行 num += 1:得到下一个需要填入的数字;
      • 更新边界:例如从左到右填完后,上边界 t += 1,相当于上边界向内缩 1。
    • 使用 num <= tar 而不是 l < r || t < b 作为迭代条件,是为了解决当 n 为奇数时,矩阵中心数字无法在迭代过程中被填充的问题。
  • 最终返回 mat 即可。

  • Java 示例:
class Solution 
    public int[][] generateMatrix(int n) 
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, tar = n * n;
        while(num <= tar)
            for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
            t++;
            for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
            r--;
            for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
            b--;
            for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
            l++;
        
        return mat;
    

  • Python 示例:
class Solution:
    def generateMatrix(self, n: int) -> [[int]]:
        l, r, t, b = 0, n - 1, 0, n - 1
        mat = [[0 for _ in range(n)] for _ in range(n)]
        num, tar = 1, n * n
        while num <= tar:
            for i in range(l, r + 1): # left to right
                mat[t][i] = num
                num += 1
            t += 1
            for i in range(t, b + 1): # top to bottom
                mat[i][r] = num
                num += 1
            r -= 1
            for i in range(r, l - 1, -1): # right to left
                mat[b][i] = num
                num += 1
            b -= 1
            for i in range(b, t - 1, -1): # bottom to top
                mat[i][l] = num
                num += 1
            l += 1
        return mat

② 模拟法(LeetCode 官方解法)

  • 模拟矩阵的生成,按照要求,初始位置设为矩阵的左上角,初始方向设为向右。若下一步的位置超出矩阵边界,或者是之前访问过的位置,则顺时针旋转,进入下一个方向,如此反复直至填入 n2 个元素。
  • 记 matrix 为生成的矩阵,其初始元素设为 0,由于填入的元素均为正数,我们可以判断当前位置的元素值,若不为 0,则说明已经访问过此位置。
  • Java 示例:
class Solution 
    public int[][] generateMatrix(int n) 
        int maxNum = n * n;
        int curNum = 1;
        int[][] matrix = new int[n][n];
        int row = 0, column = 0;
        int[][] directions = 0, 1, 1, 0, 0, -1, -1, 0; // 右下左上
        int directionIndex = 0;
        while (curNum <= maxNum) 
            matrix[row][column] = curNum;
            curNum++;
            int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] != 0) 
                directionIndex = (directionIndex + 1) % 4; // 顺时针旋转至下一个方向
            
            row = row + directions[directionIndex][0];
            column = column + directions[directionIndex][1];
        
        return matrix;
    

  • C++ 示例:
class Solution 
public:
    vector<vector<int>> generateMatrix(int n) 
        int maxNum = n * n;
        int curNum = 1;
        vector<vector<int>> matrix(n, vector<int>(n));
        int row = 0, column = 0;
        vector<vector<int>> directions = 0, 1, 1, 0, 0, -1, -1, 0;  // 右下左上
        int directionIndex = 0;
        while (curNum <= maxNum) 
            matrix[row][column] = curNum;
            curNum++;
            int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] != 0) 
                directionIndex = (directionIndex + 1) % 4;  // 顺时针旋转至下一个方向
            
            row = row + directions[directionIndex][0];
            column = column + directions[directionIndex][1];
        
        return matrix;
    
;
  • 复杂度分析:
    • 时间复杂度:O(n2),其中 n 是给定的正整数。矩阵的大小是 n×n,需要填入矩阵中的每个元素。
    • 空间复杂度:O(1),除了返回的矩阵以外,空间复杂度是常数。

③ 按层模拟(LeetCode 官方解法)

  • 可以将矩阵看成若干层,首先填入矩阵最外层的元素,其次填入矩阵次外层的元素,直到填入矩阵最内层的元素。
  • 定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。例如,下图矩阵最外层元素都是第 1 层,次外层元素都是第 2 层,最内层元素都是第 3 层。
[[1, 1, 1, 1, 1, 1],
 [1, 2, 2, 2, 2, 1],
 [1, 2, 3, 3, 2, 1],
 [1, 2, 3, 3, 2, 1],
 [1, 2, 2, 2, 2, 1],
 [1, 1, 1, 1, 1, 1]]
  • 对于每层,从左上方开始以顺时针的顺序填入所有元素。假设当前层的左上角位于 (top,left),右下角位于 (bottom,right),按照如下顺序填入当前层的元素。
    • 从左到右填入上侧元素,依次为 (top,left) 到 (top,right)。
    • 从上到下填入右侧元素,依次为 (top+1,right) 到 (bottom,right)。
    • 如果 left<right 且 top<bottom,则从右到左填入下侧元素,依次为 (bottom,right−1) 到 (bottom,left+1),以及从下到上填入左侧元素,依次为 (bottom,left) 到 (top+1,left)。
  • 填完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续填入元素,直到填完所有元素为止。
  • Java 示例:
class Solution 
    public int[][] generateMatrix(int n) 
        int num = 1;
        int[][] matrix = new int[n][n];
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        while (left <= right && top <= bottom) 
            for (int column = left; column <= right; column++) 
                matrix[top][column] = num;
                num++;
            
            for (int row = top + 1; row <= bottom; row++) 
                matrix[row][right] = num;
                num++;
            
            if (left < right && top < bottom) 
                for (int column = right - 1; column > left; column--) 
                    matrix[bottom][column] = num;
                    num++;
                
                for (int row = bottom; row > top; row--) 
                    matrix[row][left] = num;
                    num++;
                
            
            left++;
            right--;
            top++;
            bottom--;
        
        return matrix;
    

  • C++ 示例:
class Solution 
public:
    vector<vector<int>> generateMatrix(int n) 
        int num = 1;
        vector<vector<int>> matrix(n, vector<int>(n));
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        while (left <= right && top <= bottom) 
            for (int column = left; column <= right; column++) 
                matrix[top][column] = num;
                num++;
            
            for (int row = top + 1; row <= bottom; row++) 
                matrix[row][right] = num;
                num++;
            
            if (left < right && top < bottom) 
                for (int column = right - 1; column > left; column--) 
                    matrix[bottom][column] = num;
                    num++;
                
                for (int row = bottom; row > top; row--) 
                    matrix[row][left] = num;
                    num++;
                
            
            left++;
            right--;
            top++;
            bottom--;
        
        return matrix;
    
;

三、博客之星

  • 今年是我第一次参加博客之星,需要各位大佬的支持,麻烦百忙之中,抽出一点宝贵的时间,给我投一下票:https://bbs.csdn.net/topics/603955258 给我一个五星(列表会一一全部回复),不胜感激!

以上是关于数据结构与算法之深入解析“螺旋矩阵II”的求解思路与算法示例的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之深入解析“股票的最大利润”的求解思路与算法示例

数据结构与算法之深入解析“安装栅栏”的求解思路与算法示例

数据结构与算法之深入解析“最长连续序列”的求解思路与算法示例

数据结构与算法之深入解析“路径总和”的求解思路与算法示例

数据结构与算法之深入解析“斐波那契数”的求解思路与算法示例

数据结构与算法之深入解析“连续整数求和”的求解思路与算法示例