
科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载本文以 leetcode/weekly/300/b/README.md 为核心解析作者灵茶山艾府对 LeetCode 周赛 300 期 B 题spiral-matrix-iv给出的 Go 解法如何把经典 59. 螺旋矩阵 II 的“按圈填数”思路改造成“沿链表遍历填格”并借助dir4方向数组与撞墙/撞已填格则转向的统一判据写出极简循环。读完你将掌握无边界标记的螺旋遍历写法、di3方向索引技巧、以及仓库自带的testutil对拍测试体系如何验证该实现。一、问题背景与题意LeetCode 周赛 300 的 B 题要求给定一个单链表head和两个整数n、m请按螺旋顺序从左上角出发向右 → 向下 → 向左 → 向上依次循环将链表节点的值填入n × m的矩阵。矩阵中剩余位置链表节点不够时填入-1矩阵中没有节点链表为空时全部填入-1返回填充后的二维数组。该题的核心难点在于填充源不再是可随机访问的数组而是只能单向前进的链表因此所有跳步回填式写法如先分层再回填都不再适用必须让指针和链表同步前进、一步到位。仓库在 leetcode/weekly/300/b/b.go 中给出了完整实现并在 leetcode/weekly/300/b/b_test.go 与 leetcode/weekly/300/b/b.txt 中提供了对拍用例。二、核心思路59 题的改链表版原文档开门见山指出代码同 59. 螺旋矩阵 II改为在链表上遍历即可。经典 59 题的做法是按右下左上的方向不断前进每当越界或下一个位置已经填过数时就顺时针转向 90°直到填满全部n*n个格子。这一判据天然具备方向自洽性——因为矩阵是连续的填过数的地方恰好构成一堵墙。而本题只需把下一个位置的值从i1递增而来换成取自链表节点head.Val填完一格后head head.Next其余逻辑完全不变。这样一来螺旋轨迹的几何约束方向、转向规则与 59 题完全一致链表用尽后循环自然终止head ! nil作为循环条件尚未访问的格子保持初始化值-1不需要单独记录已填格数也就没有额外的计数器与提前退出分支。这就是改在链表上遍历一句话背后的全部收益代码量几乎为零增长却能同时覆盖链表提前耗尽、链表恰好填满、链表为空等所有边界情况。三、逐行拆解 Go 实现以下是 leetcode/weekly/300/b/b.go 的完整代码package main import . github.com/EndlessCheng/codeforces-go/leetcode/testutil // https://space.bilibili.com/206214/dynamic var dir4 []struct{ x, y int }{{0, 1}, {1, 0}, {0, -1}, {-1, 0}} // 右下左上 func spiralMatrix(n int, m int, head *ListNode) [][]int { ans : make([][]int, n) for i : range ans { ans[i] make([]int, m) for j : range ans[i] { ans[i][j] -1 } } for x, y, di : 0, 0, 0; head ! nil; head head.Next { ans[x][y] head.Val d : dir4[di3] if xx, yy : xd.x, yd.y; xx 0 || xx n || yy 0 || yy m || ans[xx][yy] ! -1 { di } d dir4[di3] x d.x y d.y } return ans }下面拆成四个要点逐一讲解。1. 初始化矩阵全部填 -1ans : make([][]int, n) for i : range ans { ans[i] make([]int, m) for j : range ans[i] { ans[i][j] -1 } }先用-1铺满整个矩阵。这样当链表在螺旋中途耗尽时剩余格子天然就是题目要求的-1无需任何后处理-1还兼任下文已填标记一值两用。2. 方向数组 dir4右下左上var dir4 []struct{ x, y int }{{0, 1}, {1, 0}, {0, -1}, {-1, 0}} // 右下左上(0, 1)向右(1, 0)向下(0, -1)向左(-1, 0)向上。四个方向按右下左上的顺时针顺序排列正好对应螺旋的行走次序。3. 转向判据撞墙或撞已填格d : dir4[di3] if xx, yy : xd.x, yd.y; xx 0 || xx n || yy 0 || yy m || ans[xx][yy] ! -1 { di } d dir4[di3] x d.x y d.y这是整个算法的灵魂越界判据xx 0 || xx n || yy 0 || yy m即下一个位置超出矩阵边界已填判据ans[xx][yy] ! -1即下一个位置已被访问过墙。只要满足其一就把方向下标di加一完成顺时针转向随后用新方向前进。因为dir4恰好 4 个方向di会不断增大所以取方向时统一用di 3等价于di % 4位运算更快保证索引永远落在0..3之内。4. 主循环链表驱动填充for x, y, di : 0, 0, 0; head ! nil; head head.Next { ans[x][y] head.Val // ... 计算下一步方向与坐标 }循环的三个条件与 59 题的最大区别起点始终从(0, 0)左上角出发方向下标di从 0向右开始终止条件head ! nil。链表走到尽头循环即止比填满 n*m 格的计数式写法更直接步进head head.Next在循环体内同步推进链表保证每个节点恰好落在一个格子上。注意一个细节转向判据读的是ans[xx][yy] ! -1而链表节点的值不会等于 -1题目保证节点值非负所以已填格与-1初始化值绝不会混淆。这是该判据成立的前提。四、测试用例与边界行为验证仓库用 leetcode/testutil 中预定义的链表类型驱动测试type ListNode struct { Val int Next *ListNode }测试入口 leetcode/weekly/300/b/b_test.go 通过testutil.RunLeetCodeFuncWithFile直接读取 leetcode/weekly/300/b/b.txt 中的用例做对拍func Test_b(t *testing.T) { targetCaseNum : 0 // -1 if err : testutil.RunLeetCodeFuncWithFile(t, spiralMatrix, b.txt, targetCaseNum); err ! nil { t.Fatal(err) } }leetcode/weekly/300/b/b.txt 中的两组用例非常有代表性用例 1链表恰好覆盖大部分格子留一行缺口3 5 [3,0,2,6,8,1,7,9,4,2,5,5,0] → [[3,0,2,6,8],[5,0,-1,-1,1],[5,2,4,9,7]]13 个节点、15 个格子螺旋走到第二圈时链表耗尽最后两个格子(1,2)、(1,3)保持-1验证了链表中途耗尽补 -1的分支。用例 2链表比矩阵短得多1 4 [0,1,2] → [[0,1,2,-1]]单行矩阵链表 3 个节点填完 3 格后第 4 格保持-1同时单行场景下向下越界即转向的边界也被顺带覆盖。从源码结构看leetcode/testutil/leetcode.go 中的RunLeetCodeFuncWithFile会按函数签名fNumIn fNumOut自动切分输入输出行先把[0,1,2]这类原始数组解析为链表见buildListNode再调用被测函数并逐例比对结果把手写样例 → 运行 → 比对的调试循环完全自动化。这也是该仓库在 leetcode/weekly/300/b/README.md 之外能快速验证解法的工程基础。五、复杂度分析时间复杂度O(n*m)。每个格子至多被访问一次ans[xx][yy] ! -1保证不会重入链表每个节点也只处理一次对于len(链表) n*m的情况循环次数等于链表长度严格不超过n*m。空间复杂度O(n*m)即答案矩阵本身除矩阵外只用了常数个变量x、y、di、d无额外辅助结构。六、扩展把该模式迁移到更多场景dir4 撞墙转向这套写法不止能解本题它在同类方向驱动题目中高度复用典型变体包括固定圈数的螺旋若链表刚好n*m个节点循环条件可改为计数逻辑与 59 题完全一致逆时针螺旋把dir4改为{{0,1},{1,0},{0,-1},{-1,0}}的逆序如{{0,1},{-1,0},{0,-1},{1,0}}或调整数组排列即可任意起点的蛇形/螺旋只需改动(x,y)的初始值与方向初值diBFS 波前扩展在网格类 BFS 中同一套右下左上方向数组常被直接复用。一句话总结这个模板的核心价值把下一个位置是否可达的检查统一抽象成越界 || 已填并用取模位运算di3让方向自然循环从而用最短的代码同时覆盖边界、耗尽与转向三种情况。参考阅读题解文档leetcode/weekly/300/b/README.md完整实现leetcode/weekly/300/b/b.go对拍测试leetcode/weekly/300/b/b_test.go、测试数据链表与测试工具定义leetcode/testutil/predefined_type.go、leetcode/testutil/leetcode.go赞分享科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载相关推荐7个实用算法技巧从矩阵螺旋遍历到洪水填充的完整指南7个实用算法技巧从矩阵螺旋遍历到洪水填充的完整指南 Algorithms项目是一个专注于用Java实现常见算法问题的开源项目提供了丰富的算法解决方案涵盖矩示例工程LeetCode-Go 题解59. Spiral Matrix II —— 用方向数组 访问标记实现螺旋矩阵生成LeetCode Go 题解59. Spiral Matrix II —— 用方向数组 访问标记实现螺旋矩阵生成 导读 本文以 LeetCode Go h示例工程告别繁琐验证WPF UI中INotifyDataErrorInfo的优雅实现与实战指南告别繁琐验证WPF UI中INotifyDataErrorInfo的优雅实现与实战指南 你是否曾在WPF应用开发中为数据验证而烦恼传统的ValidationUI组件桌面应用上一篇darktable 快速上手免费的 RAW 处理与摄影工作流下一篇3步装好fnm用Rust写的Node.js版本管理器快速切换版本创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考