freeCodeCamp 每日编码挑战精讲:Challenge 272 矩阵转置(Transposed Matrix)
freeCodeCamp 每日编码挑战精讲Challenge 272 矩阵转置Transposed Matrix【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇技术指南以 freeCodeCamp 每日编码挑战系列Daily Coding Challenges中的第 272 题——Transposed Matrix矩阵转置为线索完整拆解题目要求、5 个测试断言、种子代码与官方参考解法并结合 freeCodeCamp 开源仓库中该挑战的真实配置与前端实现讲解矩阵转置算法的推导过程与 JavaScript 实现技巧。读完本文你不仅能通过这道挑战还能理解assert.deepEqual式测试驱动的解题流程以及每日挑战模块在 freeCodeCamp 代码库中的组织方式。挑战背景freeCodeCamp 每日编码挑战体系本挑战位于 freeCodeCamp 课程仓库的curriculum/challenges/english/blocks/daily-coding-challenges-javascript/目录下文件名为 69e2383af7832c8032603b8e.md以挑战 id 命名。根据块配置文件 daily-coding-challenges-javascript.json该块共收录365 道挑战Challenge 1 至 Challenge 365本挑战是其中第 272 道编号位于 Challenge 271Medication Reminder与 Challenge 273ISBN-13 Validator之间。块的元数据揭示了该挑战的运行环境配置项值含义dashedNamedaily-coding-challenges-javascript块路由标识challengeType挑战内28对应dailyChallengeJs类型usesMultifileEditortrue使用多文件编辑器helpCategoryJavaScript帮助分类disableLoopProtectTeststrue禁用循环保护测试blockLayoutlegacy-challenge-list旧版挑战列表布局挑战类型28的定义可以在 challenge-types.ts 中找到const dailyChallengeJs 28;与其对应的是dailyChallengePy 29Python 版本。同一文件还说明该类型的视图为classic经典编辑器视图提交类型为tests运行测试判定并且getDailyCodingChallengeLanguage会将类型 28 映射为javascript。也就是说这道矩阵转置题正是以运行单元测试的方式自动评分的。题目要求理解矩阵转置挑战描述--description--段如下给定一个矩阵数组的数组返回它的转置版本。转置矩阵即交换行与列。例如位于索引[0, 1]的值应移动到索引[1, 0]。换言之给定一个m × n的矩阵m 行 n 列转置后得到一个n × m的矩阵原矩阵第i行第j列的元素在新矩阵中位于第j行第i列。数学上可记为result[j][i] matrix[i][j]。题目给出的示例输入与期望输出[ [1, 2, 3], [4, 5, 6] ]转置后返回[ [1, 4], [2, 5], [3, 6] ]可以看到原来 2 行 3 列的矩阵变成了 3 行 2 列原第一行[1, 2, 3]变成了新矩阵的第一列原第二行[4, 5, 6]变成了第二列。测试用例5 组断言逐条解析本挑战共提供 5 组测试--hints--段全部使用assert.deepEqual进行深比较——即逐元素比较两个数组的结构与值而非比较引用地址。这意味着返回的数组必须是全新构建的直接return matrix种子代码的默认行为必然无法通过任何测试。测试 1基础 2×3 矩阵assert.deepEqual(transpose([[1, 2, 3], [4, 5, 6]]), [[1, 4], [2, 5], [3, 6]]);transpose([[1, 2, 3], [4, 5, 6]])应返回[[1, 4], [2, 5], [3, 6]]。测试 23×2 矩阵与测试 1 互为逆运算assert.deepEqual(transpose([[1, 2], [3, 4], [5, 6]]), [[1, 3, 5], [2, 4, 6]]);3 行 2 列转置为 2 行 3 列行数、列数互换。测试 34×2 矩阵assert.deepEqual(transpose([[1, 2], [3, 4], [5, 6], [7, 8]]), [[1, 3, 5, 7], [2, 4, 6, 8]]);进一步验证非方阵场景4 行 2 列 → 2 行 4 列。测试 43×3 字符串矩阵assert.deepEqual(transpose([[a, b, c], [d, e, f], [g, h, i], [j, k, l]]), [[a, d, g, j], [b, e, h, k], [c, f, i, l]]);注意此例实为 4 行 3 列4 个内层数组每个含 3 个字符串转置后为 3 行 4 列。它证明该函数必须支持字符串元素与元素类型无关。测试 55×4 布尔矩阵assert.deepEqual(transpose([[true, false, true, false], [false, true, false, true], [true, true, false, false], [false, false, true, true], [true, false, false, true]]), [[true, false, true, false, true], [false, true, true, false, false], [true, false, false, true, false], [false, true, false, true, true]]);5 行 4 列转置为 4 行 5 列元素为布尔值。综合来看5 个测试覆盖了不同尺寸与不同元素类型数字、字符串、布尔值充分检验实现的通用性。种子代码从占位实现出发挑战的初始代码--seed--→--seed-contents--为function transpose(matrix) { return matrix; }占位实现直接返回原矩阵功能上什么都没做。你的任务就是在函数体内填充转置逻辑同时保持函数签名transpose(matrix)不变——测试正是通过这个名字来调用你的实现的。对于dailyChallengeJs类型 28挑战前端使用classic视图渲染提交时以tests类型运行上述断言。官方解法一行代码完成转置本挑战的官方参考解法--solutions--段极为精炼function transpose(matrix) { return matrix[0].map((_, i) matrix.map(row row[i])); }逐层拆解这行代码的运行机制matrix[0]取矩阵的第一行其长度即原矩阵的列数n对第一行调用map((_, i) ...)以索引i从 0 到n-1迭代——这决定了新矩阵的行数等于n在回调中执行matrix.map(row row[i])遍历原矩阵的每一行取出每行中第i列的元素组成新矩阵的第i行。例如对[[1, 2, 3], [4, 5, 6]]当i 0时matrix.map(row row[0])得到[1, 4]各行的第一个元素当i 1时得到[2, 5]当i 2时得到[3, 6]。最终结果为[[1, 4], [2, 5], [3, 6]]与题目期望完全一致。这个解法的巧妙之处在于用取第一行遍历隐式确定了列数再用内层 map 逐行取第 i 个元素完成行列交换两个map嵌套即完成了转置无需显式书写任何循环变量或临时数组。时间复杂度分析该解法遍历了矩阵的全部m × n个元素一次时间复杂度为O(m × n)其中 m 为行数、n 为列数是转置问题的最优线性下界——因为每个元素都必须移动到新位置。空间复杂度同样为O(m × n)因为必须构建一个全新的矩阵来存放结果新矩阵与原矩阵共享元素引用但对元素为原始类型数字、字符串、布尔值时值完全独立。其他可行的实现思路除官方解法外以下两种思路同样可以通过全部测试供对比理解思路一显式双层循环function transpose(matrix) { const rows matrix.length; const cols matrix[0].length; const result []; for (let j 0; j cols; j) { const newRow []; for (let i 0; i rows; i) { newRow.push(matrix[i][j]); } result.push(newRow); } return result; }外层循环遍历列j内层循环遍历行i把matrix[i][j]逐元素搬运到result[j][i]。语义最直白适合作为理解转置本质的教学版本。思路二reduce函数式写法function transpose(matrix) { return matrix.reduce( (prev, row) row.map((item, i) [...(prev[i] || []), item]), [] ); }每次遍历一行把该行的每个元素追加到结果对应行的末尾。虽然可行但频繁展开/重建数组可读性与效率都不如官方解法在此仅作拓展参考。边界情况与常见陷阱编写本题实现时需要注意以下几点均由测试结构与断言方式推导得出不能原地修改并返回原矩阵assert.deepEqual比较的是值与结构虽然原地转置方阵在数学上可行但题目要求返回转置版本且测试传入的是字面量数组原地修改同样会被检测出来返回同一个引用虽能通过deepEqual值比较但返回新数组才是标准做法也能避免污染调用方数据。必须处理非方阵测试 1、2、3、5 都是非方阵行数 ≠ 列数因此不能简单交换行列索引后原地操作必须创建行数 原列数、列数 原行数的新矩阵。元素类型无关性测试覆盖数字、字符串、布尔值实现中不要对元素做任何类型假设或运算。空矩阵与稀疏矩阵题目及测试未涉及空数组但若考虑健壮性可先检查matrix.length 0或matrix[0].length 0并返回空数组官方解法在输入为空时会因访问matrix[0]而返回undefined所以运行时保证输入非空即可。挑战在前端的呈现与验证链路理解这道题在 freeCodeCamp 学习平台上的完整运行链路有助于把握它的评分方式数据来源每日挑战按日期组织。前端路由组件 show-daily-coding-challenge.tsx 会请求${apiLocation}/daily-coding-challenge/day/${monthDay}获取当日挑战数据。数据校验返回的数据需通过 daily-coding-challenge-validator.ts 中定义的 Joi schema 校验——其中要求tests为包含text与testString的数组、challengeFiles包含文件内容、并记录challengeNumber、date、title、description等字段JavaScript 与 Python 两种语言的数据都必须齐备。入口组件学习地图页通过 widget.tsx 展示今日挑战与挑战归档两个入口按钮。语言切换classic 挑战模板如 show.tsx 与 action-row.tsx支持在 JavaScript 与 Python 之间切换语言选择结果存入本地存储键dailyCodingChallengeLanguage。课程侧挑战文件本身由 challenge-schema.js 校验其中challengeType必须是 0~33 的整数本挑战的28恰好落在dailyChallengeJs的取值上。此外isUpcomingChange: true表明该块属于即将上线的新内容块结构由同目录 JSON 与curriculum.json统一管理。总结Challenge 272 Transposed Matrix 是一道典型的二维数组操作题它要求把m × n矩阵的每个元素matrix[i][j]移动到result[j][i]。官方解法用matrix[0].map((_, i) matrix.map(row row[i]))一行代码实现时间复杂度 O(m × n)兼顾简洁与高效。通过这道题你既巩固了嵌套map与索引交换的核心技巧也体验了 freeCodeCamp 每日编码挑战描述 断言 种子代码 参考解法的标准化练习流程——全部 5 组assert.deepEqual测试在浏览器内实时运行通过即过关。如需查看本挑战的完整源文件可直接阅读 69e2383af7832c8032603b8e.md并参考同目录下其他 364 道挑战继续进阶练习。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考