蛇形矩阵算法详解:回字形与S形实现及边界控制技巧
1. 蛇形矩阵到底是什么为什么值得单独拎出来讲蛇形矩阵这个题在算法练习平台里属于那种“看起来简单、写起来卡壳、写完还想再优化”的经典题型。我第一次碰到它的时候心里想的是不就是把数字按顺序填进一个方格吗结果真动手写边界条件一多脑子就开始打结。后来刷题刷多了才发现蛇形矩阵其实是一类非常好的训练素材它能同时考察你对二维数组操作、方向控制、边界判断和循环不变量的理解。所谓蛇形矩阵通常指的是把 1 到 n² 的数字按照“蛇形”的路径填入一个 n×n 的方阵中。最常见的两种形态一种是回字形蛇形数字从外圈往内圈一圈一圈绕另一种是S形蛇形像蛇一样一行从左到右、下一行从右到左来回穿梭。不同平台、不同题目描述的“蛇形矩阵”可能指的不是同一种这一点必须先确认清楚否则你代码写得再漂亮方向搞反了也是白搭。这篇文章适合谁看如果你正在准备算法面试、正在刷算法练习题、或者单纯想找一道题来练手二维数组的操控能力那蛇形矩阵绝对值得你花时间吃透。我会从思路拆解、方向控制、边界处理、代码实现、常见坑点这几个维度把这道题彻底讲清楚。你看完之后应该能做到不看题解自己从零推导出一份稳定可靠的实现。提示不同平台对“蛇形矩阵”的定义可能有差异动手前一定要先看清楚题目给的示例输出确认是回字形还是S形这一步能帮你省下大量调试时间。2. 两种主流蛇形矩阵的形态与核心差异2.1 回字形蛇形矩阵的填充规律回字形蛇形矩阵也有人叫它螺旋矩阵。它的填充路径是这样的从左上角出发先向右走到底再向下走到底再向左走到底再向上走到底然后进入内圈重复同样的动作直到所有格子被填满。以 n4 为例输出是这样的1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7你可以看到数字沿着外圈顺时针绕了一圈然后缩进到内圈继续绕。这种形态的核心在于四个边界的动态收缩上边界、下边界、左边界、右边界每走完一条边对应的边界就往内收一格。为什么这种题容易出错因为边界收缩的时机和顺序非常讲究。你如果先更新边界再判断循环条件或者先判断再更新结果可能完全不同。我见过不少人写出来的代码外圈没问题一进内圈就多填一个或者少填一个根源就在边界更新的顺序上。2.2 S形蛇形矩阵的填充规律S形蛇形矩阵就直观多了第一行从左到右填第二行从右到左填第三行再从左到右如此反复。以 n4 为例1 2 3 4 8 7 6 5 9 10 11 12 16 15 14 13这种形态的实现难度比回字形低不少核心逻辑就是遍历每一行如果行号是偶数就正序填奇数就倒序填。但别看它简单里面也有坑——比如数字计数器在倒序填充时的递增方向以及如何用最简洁的方式表达“正序/倒序”这个切换。两种形态对比一下对比维度回字形蛇形矩阵S形蛇形矩阵路径特点顺时针螺旋向内逐行来回穿梭核心难点边界收缩与循环终止方向切换与索引控制代码复杂度较高较低常见变体逆时针、从中心向外逐列S形、对角线S形训练价值边界控制、循环不变量索引映射、条件分支搞清楚你要实现的是哪一种后面的工作才有意义。下面我分别把两种形态的实现思路和代码都讲一遍。3. 回字形蛇形矩阵的实现拆解与边界控制3.1 四边界法的核心思路实现回字形蛇形矩阵最稳妥的方法是四边界法。定义四个变量top、bottom、left、right分别表示当前未填充区域的上、下、左、右边界。初始时top0、bottomn-1、left0、rightn-1。然后按照“右→下→左→上”的顺序循环填充从左到右填充上边界填完后top加一从上到下填充右边界填完后right减一从右到左填充下边界填完后bottom减一从下到上填充左边界填完后left加一每完成一轮检查top bottom且left right是否仍然成立成立就继续下一轮。这个思路的好处是你不需要在每一步都去判断“下一个格子有没有被填过”只需要靠边界变量就能控制路径。代码写出来干净利落不容易出错。3.2 边界收缩的时机为什么这么关键我重点说一下边界收缩的时机。以填充上边界为例你从(top, left)填到(top, right)填完之后这一行就再也不会被访问了所以top可以安全地加一。但这里有个细节你在填充上边界的时候用的是当前的left和right填完之后才更新top。如果你提前更新了top那填充的起始行就错了。再来看第三步填充下边界。这时候你从(bottom, right)填到(bottom, left)填完后bottom减一。但注意执行到第三步之前right已经在第二步中被减一了所以这里的right是更新后的值。这个顺序不能乱。还有一个容易忽略的点在填充下边界和左边界之前需要额外判断top bottom和left right。为什么因为当矩阵的剩余区域只剩一行或者一列时如果不加判断可能会重复填充。比如 n3 的矩阵走到最后内圈只剩一个格子的时候如果不加判断四个步骤会依次执行导致同一个格子被填多次。def spiral_matrix(n): matrix [[0] * n for _ in range(n)] top, bottom, left, right 0, n - 1, 0, n - 1 num 1 while top bottom and left right: # 从左到右填充上边界 for col in range(left, right 1): matrix[top][col] num num 1 top 1 # 从上到下填充右边界 for row in range(top, bottom 1): matrix[row][right] num num 1 right - 1 # 从右到左填充下边界 if top bottom: for col in range(right, left - 1, -1): matrix[bottom][col] num num 1 bottom - 1 # 从下到上填充左边界 if left right: for row in range(bottom, top - 1, -1): matrix[row][left] num num 1 left 1 return matrix这段代码我用了很多次实测下来非常稳定。你可以直接拿去跑n1 到 n10 的输出都是对的。3.3 方向数组法的替代方案除了四边界法还有一种方向数组法。思路是模拟一个“小人”在矩阵里走每次按照当前方向走一步如果下一步越界或者已经填过了就换方向。方向顺序是右、下、左、上用一个方向数组来表示directions [(0, 1), (1, 0), (0, -1), (-1, 0)]这种方法的代码结构更通用适合处理各种变形的路径问题。但它的缺点是需要额外的“已访问”判断而且方向切换的逻辑如果写得不小心容易陷入死循环。我个人建议如果是单纯的回字形蛇形矩阵用四边界法就够了如果题目有变形比如从中心向外螺旋、或者不规则形状方向数组法更灵活。4. S形蛇形矩阵的实现与索引映射技巧4.1 逐行遍历的基本实现S形蛇形矩阵的实现要简单得多。核心逻辑就是两层循环外层遍历行内层遍历列。如果当前行号是偶数从0开始计数就从左到右填如果是奇数就从右到左填。def s_shape_matrix(n): matrix [[0] * n for _ in range(n)] num 1 for i in range(n): if i % 2 0: for j in range(n): matrix[i][j] num num 1 else: for j in range(n - 1, -1, -1): matrix[i][j] num num 1 return matrix这段代码短小精悍但里面有一个值得注意的细节倒序填充时j是从n-1递减到0而num仍然是递增的。这意味着数字在矩阵中的位置是倒着的但数值本身还是按顺序增长的。这一点如果搞反了输出就会变成“数字倒着增长”那就完全错了。4.2 用数学公式直接计算每个位置的值如果你想让代码更“优雅”一点可以尝试用数学公式直接计算(i, j)位置上的值而不需要模拟填充过程。对于S形蛇形矩阵第i行的起始值是i * n 1如果i是偶数位置j的值就是i * n j 1如果i是奇数位置j的值就是i * n (n - j)。def s_shape_formula(n): matrix [] for i in range(n): if i % 2 0: row [i * n j 1 for j in range(n)] else: row [i * n (n - j) for j in range(n)] matrix.append(row) return matrix这种写法的好处是时间复杂度仍然是 O(n²)但常数更小而且代码更简洁。缺点是可读性稍差如果你是在面试中手写代码建议还是用第一种模拟法因为面试官更容易看懂你的思路。4.3 S形矩阵的常见变形S形蛇形矩阵还有一些变形比如逐列S形第一列从上到下第二列从下到上如此反复。实现思路和逐行S形完全对称只需要把行和列的循环交换一下就行。还有一种变形是对角线S形数字沿着对角线方向来回填充。这种变形的难度会高不少因为对角线的边界判断比行和列复杂。如果你已经掌握了基本的S形和回字形可以拿对角线S形来练手进一步提升对二维数组路径控制的理解。5. 实操过程中最容易踩的五个坑5.1 循环终止条件写错导致死循环这是最常见的问题。在四边界法中循环条件是top bottom and left right。如果你写成top bottom and left right那么当矩阵只剩一行或一列时循环会提前退出导致部分格子没有被填充。反过来如果你在边界更新后没有重新检查条件可能会多填一轮导致数组越界。我的建议是每次更新边界之后都在心里默念一遍“现在的未填充区域是什么形状”确认边界变量是否还满足top bottom和left right。这个习惯能帮你避开大部分边界相关的 bug。5.2 奇数阶矩阵的中心格子被重复填充当 n 是奇数时矩阵最中心会有一个单独的格子。在四边界法中当top bottom且left right时这个格子会被填充。但如果你在第三步和第四步没有加if判断这个格子可能会被填充两次导致最终结果中某个数字被覆盖。我实测过n3 和 n5 是最容易出现这个问题的。解决办法就是在填充下边界和左边界之前分别加上if top bottom和if left right的判断。5.3 方向切换时索引越界方向数组法中每次移动之前都要检查下一步的位置是否在矩阵范围内以及是否已经被访问过。如果你只检查了范围而没有检查是否已访问就会陷入“在已填充区域来回走”的死循环。如果你只检查了已访问而没有检查范围就会数组越界。正确的做法是先计算下一步的坐标然后判断0 next_row n且0 next_col n且matrix[next_row][next_col] 0。三个条件都满足才移动否则换方向。5.4 输出格式不符合题目要求有些题目要求每个数字占固定宽度比如%3d或者%4d如果你直接打印数字输出会参差不齐。还有些题目要求数字之间用空格分隔行末不能有多余空格。这些格式细节虽然不影响算法正确性但会影响你的提交结果。我的习惯是先在本地用题目给的示例输入跑一遍把输出和示例逐字符对比。如果格式不对调整打印语句就行不要等到提交之后才发现问题。5.5 把两种蛇形矩阵搞混这个问题看起来很低级但实际发生的频率不低。有些题目的描述比较模糊只说“蛇形矩阵”没有明确说是回字形还是S形。如果你没有仔细看示例输出很容易写错方向。我的做法是拿到题目先看示例。如果示例的第一行是1 2 3 4第二行是12 13 14 5那就是回字形如果第二行是8 7 6 5那就是S形。确认清楚之后再动手比写完再改要高效得多。6. 常见问题速查与排查思路问题现象可能原因排查方法部分格子为0循环终止条件过早检查top bottom和left right数字重复边界更新顺序错误确认每步填充后才更新对应边界数组越界边界变量未及时收缩打印每轮边界值观察是否越界输出方向反了回字形与S形搞混对照示例输出确认形态中心格子被覆盖缺少奇数阶判断在第三、四步加if判断格式不整齐未设置输出宽度使用%3d或str(num).rjust(3)除了上面这些还有一个排查技巧在循环内部打印当前的top、bottom、left、right和num观察每一轮的变化。这个方法虽然原始但对于理解边界收缩的过程非常有效。我当初就是靠打印调试才真正搞懂了四边界法的运作机制。注意调试打印只在本地使用提交代码前记得删掉否则可能因为输出过多导致超时或格式错误。7. 从蛇形矩阵延伸出的练习方向蛇形矩阵本身不算难但它是一个很好的起点。你可以基于它做很多延伸练习逆时针回字形把方向顺序改成“下→右→上→左”其余逻辑不变。从中心向外螺旋先确定中心位置然后按照螺旋路径向外扩展边界判断会更复杂。非方阵蛇形输入 m×n 的矩阵路径规则不变但边界变量的初始值需要调整。带障碍物的蛇形矩阵中某些格子不可访问路径需要绕行这时候方向数组法更有优势。蛇形矩阵的逆运算给定一个蛇形矩阵还原出原始的数字序列或者判断它是否是合法的蛇形矩阵。这些变体在算法面试中出现的频率不低尤其是“从中心向外螺旋”和“非方阵蛇形”经常被用来考察候选人对边界控制的掌握程度。如果你能把基本形态写熟再拿这些变体练手二维数组类的题目基本就难不倒你了。我个人在实际操作中的体会是蛇形矩阵这类题看题解看十遍不如自己动手写一遍。写完之后再改一改变体比如把方向反过来、把方阵改成矩形、把起点换到中心每改一次你都会对边界控制有新的理解。踩过几次坑之后你会发现那些曾经让你头疼的边界条件慢慢就变成了肌肉记忆。

相关新闻

MarkEzd.dll二次开发全攻略:激光打标机与自动化产线集成

MarkEzd.dll二次开发全攻略:激光打标机与自动化产线集成

简介:一套面向激光打标行业开发者与 C# 工程师的 EZCAD 二次开发资源包。EZCAD 是工业激光标记场景下的常用上位机软件,支持图形编辑、文字处理、条形码/二维码生成与序列号递增;EZCAD2 在界面友好度、图形处理能力与自动化流程上进一步升级。…

2026/10/18 19:17:19 阅读更多 →
STM32F407固件库LWIP以太网移植:从PHY配置到TCP通信的排坑指南

STM32F407固件库LWIP以太网移植:从PHY配置到TCP通信的排坑指南

简介:一份面向STM32F407开发者的以太网与LWIP协议栈实战资源包,涵盖固件库驱动到网络协议栈的完整代码,适合嵌入式初学者及希望在ARM平台实现联网功能的中级开发者。压缩包内共2000个文件,包括1041个头文件、881个C源文件和78个文…

2026/10/18 19:17:19 阅读更多 →
SpringBoot+Vue毕业设计实战:抗疫物资管理系统从数据库设计到部署答辩

SpringBoot+Vue毕业设计实战:抗疫物资管理系统从数据库设计到部署答辩

每到毕业设计季,我后台总能收到一堆高相似度的问题:SpringBoot 和 Vue 到底怎么连起来?物资管理系统的数据库表要建几张才够?论文里的测试数据怎么造才不像编的?部署文档写到什么程度才算完整?这些问题背后…

2026/10/18 19:17:19 阅读更多 →

最新新闻

华为IGMP组播原理与实战:从精准调度到排障精要

华为IGMP组播原理与实战:从精准调度到排障精要

1. 为什么组播不是“群发”,而是一场精准的流量调度革命?很多人第一次听说IGMP,下意识就把它和微信群发、邮件群抄送划等号——“不就是让一台设备把数据同时发给多台设备吗?”这个理解方向错了,而且错得挺关键。我刚接…

2026/10/18 20:03:40 阅读更多 →
IPTV直播源管理系统:从m3u管理到全端稳定播放的工程实践

IPTV直播源管理系统:从m3u管理到全端稳定播放的工程实践

简介:这是一套基于Python开发的IPTV直播源管理系统可运行源码,面向具备基础Python开发与Web部署能力的技术爱好者、DIYP影音定制用户及中小型IPTV服务搭建者,解决直播源集中管理、动态配置与前端对接缺失的问题。资源包共29个文件&#xff0c…

2026/10/18 20:03:40 阅读更多 →
Maven三大生命周期与插件绑定机制:从mvn命令到构建流水线

Maven三大生命周期与插件绑定机制:从mvn命令到构建流水线

你在终端里敲下mvn clean install,回车,看着日志哗哗刷屏,最后等来一个 BUILD SUCCESS。但如果你被问一句:“这条命令到底让 Maven 做了多少事?”多半会愣一下。我刚开始用 Maven 那两年也是“会念咒不会解咒”&#x…

2026/10/18 20:03:40 阅读更多 →
STM32+TB6612电机驱动实战:PWM时序、死区防护与电流反馈闭环

STM32+TB6612电机驱动实战:PWM时序、死区防护与电流反馈闭环

简介:本资源是一份面向嵌入式初学者与STM32实践者的电机控制实战代码包,聚焦于使用STM32F103C8T6微控制器驱动TB6612FNG双H桥电机模块,解决直流电机PWM调速、正反转及小车运动状态封装控制等核心问题。压缩包共16个文件,含5个头文…

2026/10/18 20:03:40 阅读更多 →
电力系统通信设计内容深度规定:从可研到施工图的深度要求与避坑指南

电力系统通信设计内容深度规定:从可研到施工图的深度要求与避坑指南

简介:这份《电力系统通信设计内容深度规定》文档面向电力系统通信设计人员、电网调度与自动化工程师及相关专业师生,用于规范通信规划与系统通信设计各阶段的内容深度要求。文档共1个doc文件,压缩包约25KB,内容涵盖总则、电力系统…

2026/10/18 20:03:40 阅读更多 →
2026论文降AI全攻略:从检测原理到三轮返修法

2026论文降AI全攻略:从检测原理到三轮返修法

2026年,论文提交系统里的AIGC检测普遍又升了一级。最近找我咨询的同学,十个有八个开场白是同一句话:“我的论文AI率60%多,怎么降AI?”光这句话我就听了几百遍。今天这篇不绕弯子,把这套完整方案从头到尾写清…

2026/10/18 20:02:39 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →