freeCodeCamp 每日编码挑战 321:Periodic Spelling 元素周期表拼词算法解析

发布时间:2026/9/10 19:21:20
freeCodeCamp 每日编码挑战 321:Periodic Spelling 元素周期表拼词算法解析 freeCodeCamp 每日编码挑战 321Periodic Spelling 元素周期表拼词算法解析【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇技术指南以 freeCodeCamp 开源仓库中curriculum/challenges/english/blocks/daily-coding-challenges-javascript板块下的Challenge 321: Periodic Spelling挑战文件 6a15cadf5f240d05a264955f.md为核心完整讲解题目约束、全部测试用例、官方参考解中的 Map 哈希与递归回溯实现并沿仓库源码链路展示这道每日一题从课程 Markdown 到数据库种子脚本、再到前端组件的完整落地方式。读完本文你将掌握一类字典单词拆分问题的通用解法并理解 freeCodeCamp 每日编码挑战在仓库中的生产化流程。一、挑战概述用元素周期表符号拼写单词Challenge 321 是 freeCodeCamp 每日编码挑战Daily Coding ChallengeJavaScript 系列中的第 321 题题目要求实现函数getPeriodicSpelling(word)Given a word, determine if it can be spelled using element symbols from the periodic table.给定一个单词判断它能否用元素周期表中的元素符号拼写出来。核心约束如下忽略大小写输入单词的大小写不影响判定例如neon可以拆解为符号Ne、O、N返回原始大小写结果数组中的元素符号必须保持其在周期表中的原始大小写形式首字母大写、第二个字母小写并按拼写顺序排列不可拼写返回空数组若单词无法由元素符号完整拼出返回[]。题目附带了完整的 118 个元素符号列表从H、He到Og这既是解题所需的字典也决定了题目的两个关键特征单字母与双字母符号并存既有H、C、O这样的单字母符号也有He、Ne、Ti等双字母符号因此同一单词可能存在多种拆分方式映射表固定且无重复每个符号在列表中是唯一的可以直接用于建立大小写无关的查找结构。[H,He,Li,Be,B,C,N,O,F,Ne,Na,Mg,Al,Si,P,S,Cl,Ar,K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Lr,Rf,Db,Sg,Bh,Hs,Mt,Ds,Rg,Cn,Nh,Fl,Mc,Lv,Ts,Og]挑战文件的--seed--节给出了初始脚手架函数签名function getPeriodicSpelling(word) { return word; }学习者需要在此基础上补充算法实现。二、测试用例逐条拆解单一解与多重解并存挑战的--hints--节共包含 8 条断言是理解题目意图的最佳入口。前 3 条是单一解情形后 5 条则引入了多重解分支回溯与无解情形输入期望输出特点neon[Ne, O, N]单一解验证大小写归一化rational[Ra, Ti, O, N, Al]单一解全部为双字母/单字母混合yarn[Y, Ar, N]单一解carbon[C, Ar, B, O, N]或[Ca, Rb, O, N]多重解任选其一noisy[N, O, I, S, Y]或[No, I, S, Y]多重解bicycles[B, I, C, Y, Cl, Es]或[Bi, C, Y, Cl, Es]多重解optics[O, P, Ti, C, S]、[O, P, Ti, Cs]、[O, Pt, I, C, S]或[O, Pt, I, Cs]四种合法解value[]无解返回空数组多重解的断言方式值得注意hints 并没有要求返回字典序最小或符号数最少的解而是通过JSON.stringify后与多个合法路径逐一比对如carbon的path1/path2只要命中任意一条合法拆分即通过。这大大放宽了实现自由度——递归时优先取双字母还是单字母都不会影响判题结果只要回溯逻辑正确即可。const result JSON.stringify(getPeriodicSpelling(optics)); const path1 JSON.stringify([O, P, Ti, C, S]); const path2 JSON.stringify([O, P, Ti, Cs]); const path3 JSON.stringify([O, Pt, I, C, S]); const path4 JSON.stringify([O, Pt, I, Cs]); assert.isTrue(result path1 || result path2 || result path3 || result path4);value返回[]的用例则专门考察失败路径的终止条件递归必须在所有拆分尝试均告失败时返回空数组而不是抛错或返回中间状态。三、问题本质一类字典单词拆分问题将题目抽象后可以发现它本质上是经典的Word Break单词拆分问题的变体只是字典变成了 118 个元素符号且每个符号长度只能是 1 或 2输入是长度为n的字符串小写归一化后在每一步游标i处可以尝试取长度为1或2的前缀因为周期表符号最短 1 个字母、最长 2 个字母若该前缀是合法元素符号则递归处理剩余部分word[i1:]或word[i2:]递归终点是i word.length即整个单词恰好被符号序列覆盖完毕若某条路径走不通需要回溯到上一个决策点尝试另一种切分。由于符号只有 1 或 2 两种长度每个位置的分支因子最多为 2因此递归树是二叉树形态。若不考虑剪枝朴素递归的最坏情况时间复杂度为 O(2^n)但随着字符串变长前缀查表会很快失败实际分支远少于理论值。题目的输入为普通英文单词长度通常不超过 12参考解直接采用带失败返回的递归即可通过全部测试。四、官方参考解Map 哈希 递归回溯挑战文件的--solutions--节提供了官方参考实现其核心是用Map建立小写符号 → 原始符号的哈希映射再以递归回溯完成拆分function getPeriodicSpelling(word) { const elements [H,He,Li,Be,B,C,N,O,F,Ne,Na,Mg,Al,Si,P,S,Cl,Ar,K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Lr,Rf,Db,Sg,Bh,Hs,Mt,Ds,Rg,Cn,Nh,Fl,Mc,Lv,Ts,Og]; const lower new Map(elements.map(e [e.toLowerCase(), e])); function spell(word, i) { if (i word.length) return []; const one word.slice(i, i 1); const two word.slice(i, i 2); if (lower.has(two)) { const rest spell(word, i 2); if (rest ! null) return [lower.get(two), ...rest]; } if (lower.has(one)) { const rest spell(word, i 1); if (rest ! null) return [lower.get(one), ...rest]; } return null; } return spell(word.toLowerCase(), 0) ?? []; }逐行解读这段参考实现映射构建O(118)elements.map(e [e.toLowerCase(), e])将全部符号转为小写键值保留原始大小写。这样lower.get(ne)返回Ne天然满足返回原始大小写的需求也免去了对输入单词逐个字符做大小写判断递归函数spell(word, i)i是当前读取游标。终止条件i word.length返回[]作为成功基底优先尝试双字母two word.slice(i, i 2)若命中lower则递归推进 2 个字符。只有递归返回非null时才拼接结果并返回这正是回溯的关键——双字母路径失败时不会污染结果再尝试单字母双字母失败后回退到one word.slice(i, i 1)分支同样先递归后拼接失败信号用null两条路径都走不通时返回null由?? []在入口处统一转换为空数组。??空值合并保证了[]真值语义上的成功但为空不会被误替换。该实现的精巧之处在于返回值本身兼作成功标志与路径记录——null表示失败数组表示成功路径从而省去了单独维护visited或path栈的开销。由于题目不要求返回所有解或最优解找到任意一条可行路径即可提前回溯返回。五、算法复杂度与边界讨论时间复杂度每次调用至多进行 2 次Map.has()查询每次 O(1)与 2 次递归调用递归深度为 O(n)。最坏情况如全由单字母符号组成的路径例如noy→[N,O,Y]下递归树节点数为 O(2^n)但哈希查询失败会立即剪枝实际英文单词场景下远低于该上界。若需处理超长输入可引入记忆化memoization用Mapnumber, string[] | null缓存i位置的失败/成功结果将复杂度降至 O(n)空间复杂度递归栈深度 O(n)符号映射表 O(118) 常数空间边界情况空字符串spell(, 0)立即命中i word.length返回[]可视为空单词可拼写的平凡情形含数字或特殊字符的输入既不在单字母也不在双字母表中两条路径均失败最终返回[]大小写混输入如NeON入口统一toLowerCase()归一化不影响判定。值得补充的是hints 中bicycles的路径[B, I, C, Y, Cl, Es]用到了符号Es锿optics的四种合法解用到了Pt铂、Ti钛、Cs铯说明题目有意覆盖了双字母符号与单字母符号交替、且存在贪心优先双字母会走错的情形——例如carbon若贪心取双字母Ca后剩余rbonrb、r均不是合法符号必须回溯改取C。这正是考验回溯能力的设计点。六、从单道题到产品每日挑战在仓库中的完整链路Challenge 321 并非孤立存在的课程 Markdown它在 freeCodeCamp 仓库中有一条完整的生产链路理解它有助于把这道题放进真实项目的上下文中6.1 课程板块定义挑战所属板块由 daily-coding-challenges-javascript.json 定义该文件以challengeOrder数组登记了全部挑战Challenge 1: Vowel Balance 起按天递增其中 JavaScript 与 Python 两个板块一一对应challengeType标识了每日挑战的专用类型。6.2 数据库种子脚本seed-daily-challenges.ts 负责把每日挑战写入 MongoDB 的DailyCodingChallenges集合通过 helpers.ts 中的fetchChallenges(javascript | python)函数向本地 Gatsby 客户端暴露的 GraphQL 端点http://localhost:8000/___graphql查询dev-playgroundsuperblock 下的daily-coding-challenges-javascript板块并按challengeOrder升序取出description、teststestStringtext、challengeFiles等字段combineChallenges将同日期的 JS 与 Python 挑战配对校验标题、描述、测试数量一致后以 JS 挑战的id作为 MongoDB 文档_id写入包含challengeNumber、date、javascript与python双语言的统一文档脚本硬性断言挑战总数为365起始日期为2025-08-11T00:00:00.000Z此后每天递增一天并注释强调发布后不可更改起始日期这是每日挑战每日一题节奏的正确性保证。运行方式在 tools/daily-challenges/README.md 中有明确说明复制sample.env为.env、安装依赖、以显示即将上线内容upcoming changes shown模式启动主客户端然后在tools/daily-challenges目录执行pnpm seed-daily-challenges完成播种。6.3 API 与前端呈现API 侧daily-coding-challenge.ts 与其测试文件 daily-coding-challenge.test.ts 提供按日期读取挑战数据的服务端接口前端侧widget.tsx、calendar.tsx 及 helpers.ts 实现挑战展示组件与日期计算逻辑E2E 侧daily-coding-challenge.spec.ts 覆盖了/learn/daily-coding-challenge/08-11等日期路由、无效日期重定向到 archive、以及通过种子命令构造测试数据等端到端场景。这意味着 Challenge 321 这类题目的 Markdown 是单一事实来源它既驱动学习者页面上的题目与测试运行又被种子脚本转化为按日期发布的每日挑战数据最终通过 API 呈现给用户。对学习者而言在本地运行pnpm seed-daily-challenges后即可在/learn/daily-coding-challenge/日期页面实际作答第 321 题。七、总结从拼词题到通用解题思维Challenge 321: Periodic Spelling 表面是一道元素符号拼词趣味题实际考察的是三类核心能力哈希映射的设计把 118 个符号用小写键建立Map同时解决大小写归一化与还原原始符号大小写两个需求是空间换时间的典型手法递归回溯的终止与信号设计用null作为失败信号、以返回值同时承载是否成功与路径内容并用?? []兜底是简洁且不易出错的分治写法多解宽容的判题设计hints 允许多条合法路径中的任意一条启示我们在实现时不必追求唯一最优解正确回溯 任意可行解即可通过验证。掌握这类固定长度词元 查表 回溯的套路后你可以把它直接迁移到其他场景——如 IP 地址/电话号码分段、罗马数字解析、以及经典 Word Break 问题。结合 官方参考解 动手实现一遍再对比仓库中每日挑战的完整生产链路既能巩固算法功底也能理解开源课程内容如何被工程化地构建、测试与发布。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询