pyhton 螺旋矩阵(指针-矩阵-中等)含源码(二十六)

问题说明(含示例)

问题描述:给定一个正整数 n,生成一个 n x n 的正方形矩阵,矩阵中包含 1 到 n² 的所有元素,且元素按顺时针螺旋顺序排列。

示例输入 输出 解释n = 3 [[1,2,3],[8,9,4],[7,6,5]] 元素从 1 到 9 按顺时针螺旋排列:先右移填充第一行,再下移填充最后一列,再左移填充最后一行,再上移填充第一列,最后填充中心元素n = 1 [[1]] 仅 1 个元素,直接返回包含 1 的单元素矩阵n = 2 [[1,2],[4,3]] 元素 1→2→3→4 按顺时针螺旋排列(右移→下移→左移)

解题关键

核心思路是通过控制边界的螺旋遍历模拟填充过程,利用 "上、下、左、右" 四个边界变量动态收缩范围,按顺时针顺序(右→下→左→上)依次填充元素,直到所有数字(1 到 n²)都被填入矩阵。

具体步骤如下:

  • 初始化 n x n 矩阵(填充 0 占位);
  • 定义四个边界:top(上边界,初始为 0)、bottom(下边界,初始为 n-1)、left(左边界,初始为 0)、right(右边界,初始为 n-1);
  • 从 1 开始填充数字,直到填充完 n²:
    1. 从左到右填充上边界行,完成后上边界上移(top += 1);
    2. 从上到下填充右边界列,完成后右边界左移(right -= 1);
    3. 若上边界未超过下边界,从右到左填充下边界行,完成后下边界下移(bottom -= 1);
    4. 若左边界未超过右边界,从下到上填充左边界列,完成后左边界右移(left += 1);
  • 重复上述步骤,直到所有数字填充完毕。

核心逻辑 + 关键细节

一、核心逻辑:如何模拟顺时针螺旋填充?

通过 "边界收缩" 控制填充范围,将螺旋过程拆解为四次方向填充,每次填充后调整边界,确保不重复填充已有元素:

  1. 方向顺序固定:严格按照 "右→下→左→上" 的顺时针顺序填充,符合螺旋的自然轨迹;
  2. 边界动态调整:每完成一个方向的填充,对应的边界向内收缩(如右移填充完第一行后,上边界下移,避免再次填充该行);
  3. 边界有效性判断 :在填充 "左" 和 "上" 方向时,需判断当前边界是否仍有效(如top <= bottom确保下边界行未被填充过),避免越界或重复填充。
二、关键细节:避坑与优化点
  • 矩阵初始化[[0]*n for _ in range(n)]创建 n x n 矩阵,避免浅拷贝问题(如[[0]*n]*n会导致修改一行全部同步);
  • 循环终止条件 :以 "当前填充数字current <= n²" 为循环条件,确保所有数字都被填充;
  • 方向填充的范围控制
    • 左到右:列从leftright(包含两端);

    • 上到下:行从topbottom(包含两端);

    • 右到左:列从rightleft逆序,步长为 -1);

    • range 函数参数含义 range(right, left - 1, -1) 用于生成从右边界到左边界的逆序列索引,具体参数作用:

      • start = right:起始列索引为当前右边界(最右侧的列);
      • stop = left - 1:终止条件为 "小于 left - 1 时停止"(实际会包含 left 列,因为当 col 减到 left 时,下一次会是 left - 1,此时停止);
      • step = -1:步长为 -1,表示列索引从大到小递减(即 "从右向左" 遍历)。
    • 下到上:行从bottomtop(逆序,步长为 -1);

  • 边界收缩的时机 :每个方向填充完成后立即收缩边界(如右移填充后top += 1),避免下一次填充时重复使用该边界。

对应代码

python 复制代码
def generateMatrix(n: int) -> list[list[int]]:
    # 初始化 n x n 矩阵,用0占位
    matrix = [[0] * n for _ in range(n)]
    # 定义四个边界
    top, bottom = 0, n - 1
    left, right = 0, n - 1
    current = 1  # 从1开始填充
    
    while current <= n * n:
        # 1. 左到右填充上边界行
        for col in range(left, right + 1):
            matrix[top][col] = current
            current += 1
        top += 1  # 上边界下移
        
        # 2. 上到下填充右边界列
        for row in range(top, bottom + 1):
            matrix[row][right] = current
            current += 1
        right -= 1  # 右边界左移
        
        # 3. 右到左填充下边界行(需确保上边界未超过下边界)
        if top <= bottom:
            for col in range(right, left - 1, -1):
                matrix[bottom][col] = current
                current += 1
            bottom -= 1  # 下边界上移
        
        # 4. 下到上填充左边界列(需确保左边界未超过右边界)
        if left <= right:
            for row in range(bottom, top - 1, -1):
                matrix[row][left] = current
                current += 1
            left += 1  # 左边界右移
    
    return matrix

对应的基础知识

实现该算法需掌握以下 Python 基础概念与操作:

  1. 二维列表的创建

    • 语法:[[0]*n for _ in range(n)] 生成 n 行 n 列的矩阵,每行是独立的列表;
    • 注意:避免使用[[0]*n]*n,否则修改一行会导致所有行同步变化(浅拷贝特性)。
  2. 循环与 range 的使用

    • for 循环:用于按方向遍历矩阵的行或列;
    • range 函数:
      • 正向遍历:range(left, right + 1) 覆盖从 left 到 right 的所有列;
      • 逆向遍历:range(right, left - 1, -1) 覆盖从 right 到 left 的所有列(步长为 -1)。
  3. 边界变量的更新

    • 通过top += 1right -= 1等操作动态调整边界,控制填充范围;
    • 边界变量是 "状态标记",直接决定下一次填充的起点和终点。
  4. 条件判断语句

    • if top <= bottomif left <= right 用于判断边界有效性,避免在矩阵填充后期(如只剩一行或一列时)出现重复填充。

对应的进阶知识

该问题涉及螺旋遍历的通用逻辑、复杂度分析与边界处理技巧:

  1. 时间复杂度:O (n²)

    • 矩阵共有 n² 个元素,每个元素仅被填充一次,因此总操作次数为 n²,时间复杂度为 O (n²)。
  2. 空间复杂度:O (n²)

    • 需创建 n x n 的矩阵存储结果,属于输出必要空间,因此空间复杂度为 O (n²)。
  3. 螺旋遍历的通用模型

    • 核心是 "方向循环 + 边界收缩",适用于所有螺旋遍历类问题(如螺旋读取矩阵、螺旋填充矩阵);
    • 方向顺序可灵活调整(如逆时针),只需修改填充的方向顺序和边界收缩逻辑。
  4. 奇偶 n 的差异处理

    • 当 n 为奇数时,最后会剩余中心一个元素(如 n=3 时的 9),通过第四次边界判断(left <= right)后,会进入最后一次左到右填充,自动处理中心元素;
    • 当 n 为偶数时,所有元素会被四次方向填充完整覆盖,无单独中心元素。

编程思维与启示

  1. "拆解问题" 的思维

    • 将复杂的 "螺旋填充" 拆解为 "右→下→左→上" 四个简单的直线填充步骤,通过循环重复这四个步骤,降低问题复杂度;
    • 启示:面对复杂轨迹问题(如蛇形、螺旋),可拆解为有限的基础方向,通过循环实现。
  2. "边界控制" 的重要性

    • 用边界变量(top/bottom/left/right)精准控制填充范围,避免手动计算索引(易出错);
    • 启示:涉及区间或范围的问题(如子数组、矩阵遍历),优先用边界变量标记范围,而非直接操作索引。
  3. "状态同步" 的维护

    • 每次填充后立即更新边界(如填充完上边界后top += 1),确保下一次填充的状态正确;
    • 启示:操作与状态变更需同步,避免因状态滞后导致逻辑错误(如重复填充同一行)。
  4. "条件判断" 的必要性

    • 通过if top <= bottom等判断避免无效填充,适应不同 n 的场景(如 n=1 时无需填充下和左方向);
    • 启示:算法需具备 "鲁棒性",通过条件判断处理边界情况,避免一刀切逻辑。
相关推荐
智能化咨询6 小时前
矩阵的奇异值分解(SVD)核心原理与图形学基础应用
矩阵
西***63476 小时前
从信号处理到智能协同:高清混合矩阵全链路技术拆解,分布式系统十大趋势抢先看
网络·分布式·矩阵
AIGC_北苏6 小时前
大语言模型,一个巨大的矩阵
人工智能·语言模型·矩阵
坚持编程的菜鸟6 小时前
LeetCode每日一题——二进制求和
c语言·算法·leetcode
言之。6 小时前
Andrej Karpathy 演讲【PyTorch at Tesla】
人工智能·pytorch·python
赵谨言7 小时前
基于Python楼王争霸劳动竞赛数据处理分析
大数据·开发语言·经验分享·python
Glink7 小时前
现在开始将Github作为数据库
前端·算法·github
WWZZ20257 小时前
快速上手大模型:机器学习6(过拟合、正则化)
人工智能·算法·机器学习·计算机视觉·机器人·slam·具身感知
ceclar1237 小时前
C++Lambda表达式
开发语言·c++·算法