力扣高频 888 规格说明
这本书是一个面向力扣中国区面试刷题的紧凑练习页面。
字体与数学排版契约
本书继承 BOOK_STYLE.md 的全站书籍样式契约:正文、标题、导航、
控件、表格、图注和普通 UI 文本默认使用苹方字体栈;代码块、行内代码、
终端片段和代码编辑器默认使用 Cursor/LeetCode 代码字体栈
Monaco, "Cascadia Code", Consolas, "Courier New", ui-monospace, SFMono-Regular, Menlo, monospace。题面约束、变量、数组、矩阵、复杂度、数值范围
和指标能用 LaTeX/KaTeX 表达时必须优先使用 LaTeX。
数据契约
目标排名来自 2026 年 5 月 16 日力扣题库按“出题频率”排序后的结果。页面 排除了题库顶部钉住的每日一题,因为它不属于频率排序本身。目标源排名是 Top888。
默认题目列表会做去重。明显重复题按照规范化后的中文题名识别,例如 LCCI/LCR 和力扣主站里同名或等价的题。保留频率排序更靠前的一题,移除的 题会记录到页面里的去重核对区,方便人工复查。保留行展示的 top 编号仍然 是原始频率排名,所以被移除的重复题会留下有意的编号空缺。
Hot100 成员来自公开的 Hot100 题单。如果某道 Hot100 题不在 Top888 内,它 会作为补充题追加展示;这种题没有 Top888 编号,但仍保留它在频率序列中的 位置,用来计算 Hot100 内部的频率顺序。
字节跳动成员来自力扣中国区企业题库 favorite:bytedance-all、
bytedance-thirty-days、bytedance-three-months、
bytedance-six-months 和 bytedance-more-than-six-months。页面对应
提供五个筛选:字节全部、近 30 天、近 3 个月、近 6 个月和 6 个月前。
目标全量字节题库有 1,503 道题,并按企业题库里的出题频率排序。不在
Top888 或 Hot100 补充里的字节题,会追加在后面,并保留它自己的字节高频
编号。
字节企业题库数据由 npm run sync:leetcode-bytedance 生成。力扣中国区的
企业 favorite 需要登录态 Plus 访问,因此完整同步通过 LEETCODE_CN_COOKIE
传入登录态。脚本使用公司页实际调用的 favoriteQuestionList GraphQL,
按 skip 和 limit 分页,并用
{ sortField: "FREQUENCY", sortOrder: "DESCENDING" } 排序。如果当前环境
拿不到认证后的公司列表,脚本会写入明确标记的 legacy Top888 fallback。
脚本也支持合并从 Chrome 已登录公司页渲染结果导出的 Top100 bucket:
这些条目标记为“官方页 Top100”,并覆盖对应的字节全量、近 30 天、近
3 个月、近 6 个月或 6 个月前排名;legacy 条目仍保留为“旧数据”。页面
必须展示每个 bucket 的来源,不会把 1,503 道公司题库伪装成已经完整同步。
灵神题单来自灵茶山艾府《如何科学刷题》中的 12 个专题链接:滑动窗口与
双指针、二分算法、单调栈、网格图、位运算、图论算法、动态规划、常用
数据结构、数学算法、贪心与思维、链表/树/回溯和字符串。同步脚本是
npm run sync:leetcode-lingshen,它从力扣讨论帖读取题目原始顺序、专题
分组、难度分和会员题提示,再用力扣题库元数据与本地公开 Doocs 资料补齐
标题、标签、题面预览、思路预览和通用检查点。不在 Top888、字节题库或
系列补题中的灵神题,会作为“灵神补充”追加到本地题册,仍参与搜索、展开、
本地状态、顺序流和推荐流。
周赛难度分通过 npm run sync:leetcode-contest-ratings 生成,主数据源是
公开的 zerotrac/leetcode_problem_rating。页面把这份分数合并到整本
题册,而不是只在灵神题单里展示:主列表有独立“分数”列,标签、相关题、
系列/分类题单和搜索索引都必须携带同一套分数字段;有周赛来源的题还要保留
比赛名称、题号位置和来源说明。没有 zerotrac 记录但灵神题单提供难度分的
题,可用灵神难度分作为兜底,并在内部保留来源标记。没有任何分数来源的题
显示为 --,不得伪造估算分。
官方代码模板通过本地同步脚本生成,而不是由 GitHub Pages 页面运行时跨域
请求力扣。脚本命令是 npm run sync:leetcode-templates,默认优先访问
力扣中国区公开 GraphQL 的 question.codeSnippets,在中国区接口被限流
或返回挑战页时,退回到 LeetCode global 的同名官方模板。脚本支持用
LEETCODE_CN_COOKIE 或 LEETCODE_COOKIE 走登录态,也支持
--missing-only 合并既有结果后只补缺失题。同步目标是去重后的整本题库,
包含只来自字节企业题库的补充行,所以补充题也必须拥有和 Top888 行一致的
官方编辑器默认代码。同步结果写入 src/data/leetcode-code-templates.ts,
页面只读取这份静态数据。
只来自字节企业题库的补充行不能展示通用占位学习文本。如果某道字节题不在
主题库数据中,src/data/leetcode-bytedance.ts 需要携带本地题面预览、题目
标签、思路预览和通用检查点。这些字段来自力扣公开题面内容和本地学习摘要;
示例仍然不会进入本地渲染题面。
官方数据范围通过 npm run sync:leetcode-constraints 生成。脚本读取页面
实际渲染的合并题目列表,从力扣中国区公开题面的 提示 / Constraints
列表里抽取数据范围;如果付费题在力扣 API 中不返回题面,则退回到已有
public Doocs reference 对应的题面。同步结果写入
src/data/leetcode-problem-constraints.ts。页面上的每一道题都必须有非空
数据范围。练习面板会把这些范围作为题面末尾的一句紧凑约束条件展示,不
另起带边框的独立区块,也不使用项目符号列表。由于这些约束大多是数学表
达式,约束之间在所有语言里都使用带空隙的半角分号;每条约束自身的结尾
句号或分号会在拼接前剥掉,避免出现 。 ; 这类破碎标点。中文标签等纯中文
说明仍按中文标点处理。约束文字必须使用接近题面正文的清晰字重和颜色,不得
做成发灰、发虚的辅助说明。题面和约束句统一使用更大的苹方优先阅读字体,
并保持普通视觉字重。少数官方题面没有单独列出数据范围的题,例如部分数据库题,会
明确提示以题面中的表结构或输入定义为准。
题面和数据范围里的数学排版通过 npm run sync:leetcode-math 生成。脚本
读取页面实际渲染的同一份合并题目列表,归一化常见力扣数学片段,并把
KaTeX 预渲染后的静态 HTML 写入
src/data/leetcode-problem-math.ts。上标、下标、矩阵或网格尺寸、Big-O、
数值范围和比较链都必须渲染成数学,而不是 n 2、m x n、10 9 这类
破碎纯文本。题面里明显作为变量或程序标识符出现的 n、height、
height[i]、haystack、needle 等,也应在不破坏句子阅读的前提下渲染
为行内数学;普通叙述数字若不是公式或范围的一部分,则保留文本。本地题面
和题目 hover 预览不展示官方示例段;示例只作为运行官方样例流程的数据来源,
不混进题面正文。若旧的 statementPreview 是被截断的预览文本,生成脚本
必须使用本地官方题面覆盖文本,避免渲染出半句、断开的括号或压扁的列表。
页面只读取这份已转义的生成 HTML,并全局引入 KaTeX CSS。
发布题面或数学相关改动前,npm run check:leetcode-math 必须通过。
官方题面视觉片段通过 npm run sync:leetcode-statement-assets 生成。脚本读取
同一份合并后的题目列表,从力扣中国区官方题面 HTML 抽取并清洗图片,以及示例
或数据范围之前出现的表结构类表格,写入
src/data/leetcode-problem-assets.ts。页面只在展开后的答题区题面里渲染这些
静态片段;题目标题 hover 预览保持纯文本,页面运行时不向力扣 API 请求题面
资产元数据。
官方相关题也通过本地同步脚本生成。脚本命令是
npm run sync:leetcode-related,会对 Top888、Hot100 和字节补充题逐题
读取力扣中国区公开 GraphQL 的 question.similarQuestions 字段,并把静态
结果写入 src/data/leetcode-related.ts。页面运行时不直接请求相关题。
构建页面时会把官方相关题、基于本地 slug 自动识别的同系列题,以及少量按
共享标签和频率顺序挑出的同路线高频题合并展示,例如 house-robber、
house-robber-ii 和 house-robber-iii 会被识别为同一系列。
之前已核实到的精确出题频率会继续保留。新增题目如果只能确认频率顺序,
但公开响应不暴露精确百分比,则会用 约 或补充来源标记出来,避免把估算
值和精确值混在一起。
公司追问和通用检查点分开记录。只有公开的 LeetCode Discuss 面经页面同时 能核实公司、题目或高度相关变体、以及追问内容时,才会收录为公司追问。 每条公司追问都会保存简短解答、公司名和来源链接。如果某题没有找到公开 来源,页面会明确显示暂无公开核实来源,而不会按推测填公司。
题目学习内容必须优先服务单题讲解,而不是只拼接标签级模板。approachPreview
需要写出这道题自己的状态、不变量、边界和为什么这样做能得到正确答案;如果
存在从朴素解法到最优解的关键压缩,例如动态规划压成贪心边界,也要明确写出。
followUps 必须是这题自然会被追问的具体变体或易错点,并给出可直接用于
面试回答的短解。implementationReferences 至少要包含可提交的主解;对高频
且容易误解的题,应补一个朴素基线、路径还原、不可达处理或其它能解释主解
取舍的参考实现。通用的“边界样例、复杂度、空间压缩”只能作为补充,不能
替代单题专属内容。
页面契约
页面不展示全站顶栏;书名区保持工作台式紧凑尺寸,首屏不展示大封面。统计 和次要元信息放在练题列表下方。题目列表是页面的核心工作区,桌面宽度下 打开页面无需滚动就应能看到题目行;表格应贴合内容容器展示,不使用列表 内部横向滚动条。
每一行展示和刷题最相关的编号:
- Top888 高频顺序编号;
- Hot100 频率顺序编号,而不是题单原始分类顺序;
- 字节企业题库高频编号;
- 力扣原始题号,放在可点击题目链接里。
思路、实现、标签和相关题控件都贴着题目标题放在同一列里,避免鼠标需要 横跨到表格右侧。题目链接本身点击时仍负责打开力扣,但 hover/focus 时必须 展示和其它预览一致的暖黄色大块浮层,内容是本地题面和紧凑数据范围;题面 同时也会在打开练习区后展示在编辑器上方。向右轻微移动到「思路」时展示 思路;再向右移动到「实现」时展示 reference implementation;最后移动到 「标签」时展示标签和补充徽标。「相关」预览先展示同系列题,再展示力扣官方 相关题,最后展示紧凑的同路线高频题。已经收进本书的相关题会直接打开本地 练习区;同系列题分区也提供紧凑入口,可直接按该系列启动顺序流。不在本书里 的相关题跳到力扣中国区,并保留力扣返回的付费标记。所有预览触点都默认以 小按钮或短文本紧贴题名,不额外撑高行高。
题目标题、思路、实现、标签、相关题、猜你想练、快捷键和日统计这些 hover
信息都必须使用页面自己的暖黄色块状浮层。页面不得依赖浏览器原生 title
灰条,也不得用自定义伪元素做灰色条状 hover 提示。过去灰条里的“悬浮查看
某内容;点击或 Enter/Space 固定展开”这类说明,要放进对应黄色浮层的开头;
没有黄色浮层的普通按钮只保留可访问的 aria-label 和快捷键总表。
验收时,练题页面渲染后的 DOM 不应留下任何会触发浏览器原生灰条的 title
属性。
所有页面自有 hover 浮层都默认必须支持可追踪悬浮。触发控件和浮层之间即使
有视觉间距,也必须用透明、可命中的桥接区域或等价的延迟关闭机制连接起来,
让鼠标从触发控件向下或向上移动到浮层本体时不会闪退。浮层保持打开的热区
包括触发控件、桥接区域和浮层本体;只有指针离开这三者之后,才允许关闭
hover 浮层。这个要求适用于题目标题、思路、实现、标签、相关题、分类/系列
题单里的“思路”、猜你想练、快捷键、日统计、成就,以及后续新增的所有 hover
信息。可交互或可滚动浮层不得使用会导致鼠标进入浮层后立即关闭的
pointer-events: none;如果浮层因为空间不足改为向上打开,桥接区域也必须
同步切到触发控件上方。验收时,用普通鼠标轨迹从触发控件中心移动到浮层首行、
滚动区域或内部按钮,浮层必须保持可见,不能闪烁、关闭或要求用户先点击固定。
去重核对区位于练题列表下方,默认折叠。它会列出每一道被移除的重复题、 保留的题,以及两者原始频率排名,同时不占用首屏题目行之前的空间。猜你 想练排序规则、Chrome 扩展安装说明这类较长的次级说明,也要和去重核对 放在同一个折叠区域组里,并紧跟在去重核对下面,避免长说明散落到统计和 设置区域之后,保持页面规整、整洁、美观。
分页支持 10、20、50、100 和自定义每页数量,默认每页 20 道。题目表格上方 和下方都必须有分页控件,支持首页、上一页、下一页、末页和输入页码跳转。 当前焦点不在搜索、筛选、选择器、练习编辑器或其他可编辑控件中时,左右 方向键可以翻页。
页面顶部必须保持紧凑。页面开头只保留一行书名/说明/入口按钮,用于快速 定位当前书;摘要和统计放到练题列表之后。搜索、筛选、分页和题目行仍然是 第一视觉优先级,打开页面后不应被过度滚动成本遮挡。
筛选按范围、字节和状态三组摆放。范围支持全部、Hot100 和公司追问;字节 支持全部、近 30 天、近 3 个月、近 6 个月和 6 个月前;状态支持未做、 需思考和未熟练。搜索以题目本身为主:题号、中文题名和英文 slug 权重最高, 系列名、灵神专题名和标签次之,Hot100、字节、灵神等集合标记只作为低权重 辅助命中。搜索排序先看相关性,再用当前筛选下的原有顺序打平分;不再让 通用检查点、公司追问、实现来源或相关题文本把高频但题名无关的题排到前面。 搜索支持基础模糊匹配:大小写和全半角归一、空格/连字符等价、token 全匹配、 前缀/包含匹配,以及短词的有序字符匹配。
每行支持点击展开本地练习区。练习区只保存到当前浏览器的本地存储,提供
语言选择、官方代码模板初始化、草稿、复制、重置、跳转力扣和可选扩展提交。
代码草稿按北京时间自然日滚动:页面首次见到该浏览器时只记录当天日期,
之后一旦进入新的北京时间日期,就自动清空所有代码草稿,让每天从官方模板
或本地 fallback 模板重新开始;这个日切只影响代码草稿,不清空做题状态、
点击记录、每题 PB 或每日计时历史。页面底部提供一个日切自动重置开关,
默认开启;同一个浏览器里可以把它关闭。
语言下拉来自同步到本地仓库的官方 codeSnippets;如果某题暂时缺失官方
模板,页面使用本地 fallback 模板并明确提示。练习代码编辑区使用原生
textarea 叠加本地语法高亮层,覆盖官方模板里的常见语言,避免引入重量级
编辑器依赖。原生编辑器仍要保留接近力扣的基础编辑手感:回车继承当前行
缩进,并在左大括号、左中括号、左小括号或 Python 冒号后自动多缩进一层;
Tab 和 Shift+Tab 支持对当前行或选中多行缩进/反缩进;在只有缩进的行
输入右括号、右中括号或右大括号时,会自动回退一层对齐;在行首缩进区域
按普通 Backspace 时,会按 4 空格 tab stop 回删,例如 8 个空格退到 4 个、
6 个空格退到 4 个、不足 4 个空格时直接退到行首。编辑器左侧固定
展示行号,行号会跟 textarea 和语法高亮层同步滚动。编辑器默认高度等于
当前代码行数再多一行,并随着代码增长自动增高,直到一个有边界的最大高度;
这样短模板不会留下大块空白,也尽量减少写题时内部滚动看不到上下文的问题。
工具栏保留紧凑的“高度”切换,需要稳定面板大小时可切到 14 行可见代码的
固定高度;固定高度模式仍可拖拽调整
并支持内部滚动。自适应高度下继续输入到视口底部附近时,页面要按当前光标
所在行自动滚动,保持光标处在舒适的可写区域,避免用户一边写代码一边手动
追着页面下滚。第一次展开默认模板、重置草稿或切换语言生成新模板时,光标
会自动落到用户真正开始写实现的函数体位置。练题页面 UI 默认使用苹方优先的
文字栈,题面、浮层、计时指标、快捷键提示和奖励浮层都跟随这套默认字体,并
退回到 Apple 和常见系统黑体;页面字体不再提供单独切换,也不改变代码编辑器
字体。页面底部提供编辑器主题、字体、字号和行距选择;默认浅色主题使用和
页面一致的背景色,同时保留 Cursor Light+ 的代码配色;默认编辑器字体跟当前
Cursor 配置保持一致,即
Monaco, 'Cascadia Code', Consolas, 'Courier New', monospace。默认字号和
行距使用更紧凑的刷题密度,减少短模板占用的垂直空间;其它主题、等宽字体、
字号和行距只作为可选项保存到当前浏览器。
刷新页面时,页面会从当前浏览器本地存储恢复上一次练题视图:筛选、搜索词、
每页数量、页码、展开的题目、页面滚动位置、编辑器选区和编辑器内部滚动位置。
如果同步后的题目数据变化导致已保存题目在当前筛选下不可见,页面会退回到
匹配的筛选列表,不强行打开编辑器。
直接练题链接会覆盖这份本地恢复状态。URL 带 ?problem=<slug> 或
?id=<frontendId> 时,页面会清空本地搜索和筛选,跳到匹配题目所在页,
展开该题答题区,并自动聚焦本地编辑器。这个链接只决定打开哪道题,不会重置
或覆盖用户已有的本地代码草稿;如果 URL 指向未知题目,页面继续使用本地保存
的视图。每个题目行在预览按钮旁提供一个紧凑的弯箭头分享入口,会复制一条随机
邀请文案和当前语言页面的 problem=<titleSlug> URL,并在分享按钮附近的临时
提示里展示本次实际复制的全文。提示会在短暂停留后自动消失,也可以在下一次页面
点击时立即收起,让用户粘贴给别人时可以直接邀请对方打开同一道题。中文邀请文案
改为手写的朋友互发题口吻,覆盖求教、撒娇、激将、装弱、一起做和求 AC 等语气,
随机时会避开最近用过的语气,让连续分享不容易撞型。
打开练题编辑器时,清洗后的本地题面会作为普通前端 UI 默认展示在代码编辑器
正上方,字号保持适中,不写进代码注释;题面区可以收起,也可以重新显示,
这个显示偏好保存到当前浏览器。
打开题目或用键盘在题目间切换时,页面要把题目标题行、题面和编辑器一起框到
sticky header 下方,让编辑器保持焦点的同时,不把上方的题目标题和本地题面
顶出视口。
快捷键对齐力扣的核心肌肉记忆:Cmd+' 运行官方示例用例,Cmd+Enter
完整提交到力扣;编辑器内 Cmd+/ 按当前语言切换行注释,并保留当前选区或
光标位置;Cmd+Left 和 Cmd+Shift+Left 会优先移动或选中到当前行第一个
非空白代码字符,只有已经在代码开头时才退到真正行首,和力扣编辑器的缩进
感知行首行为一致。练题导航也要键盘优先:Option+J 或 Option+Down 打开并聚焦
下一道可见题的答题区,Option+K 或 Option+Up 打开并聚焦上一道可见题
的答题区。常用页面动作也必须可键盘完成:/ 聚焦搜索,Option+1 到
Option+3 切范围筛选,Option+4 到 Option+8 切字节筛选,Option+9、
Option+0 和 Option+- 切状态筛选,Option+P 聚焦页码跳转,
Option+Left 和 Option+Right 跳到首页和末页。当前题工具栏支持
Cmd+Option+L 聚焦语言选择、Cmd+Option+C 复制代码、Cmd+Option+H
切编辑器高度、Cmd+Option+R 重置当前草稿、Cmd+Option+D/S/M
切做过/思考/熟练状态;计时区支持
Cmd+Option+T 重开当前题计时、Cmd+Option+Shift+S 重开本次计时、
Cmd+Option+Shift+T 清当前题 PB 和上次 AC。分页附近保留紧凑的快捷键
入口,列出所有快捷键,不再在页面尾部额外撑开一个很高的快捷键块。所有
hover 浮层都要允许鼠标从触发点自然移动到浮层内容区域,离开浮层后再收起。
计时必须自动触发。日统计默认压缩为 hover/focus 弹层,避免点击展开内容
挤占首屏列表空间。打开某题或用键盘切到某题答题区时,页面自动从 0 开始
正向记录当前题耗时,不需要用户点开始。当前题计时和本次 session 计时
只累计前台练习时间:页面被隐藏或浏览器窗口失焦时暂停,页面重新可见且
获得焦点后从已累计时间继续。这里不使用 idle timeout,因为读题、调试和
不敲键盘的思考也属于有效刷题时间。完整提交到力扣并返回 Accepted 时,
页面用“最近一次切入/打开该题”之后累计到的前台时间结算本次耗时,自动
把题目标记为做过,更新本题上次 AC、本题 PB,并把当前题计时重置给可能
的再次练习。运行样例通过不计入 AC。页面加载时同时启动本次 session
计时,展示当前题耗时、本次总耗时、本次不同题 AC 数、本次平均耗时、
今日/历史日记录、连续天数、近 7 日题量和当前题 PB。“今日/纪录”指标必须
使用没有空格的紧凑斜杠格式,例如 38/42,在桌面、平板和 320 px 手机宽度
下都不能被省略号截断,也不能压到相邻指标卡片;计时面板应在单个指标卡片
被压窄前先重排成更少列。可见标题负责解释含义,可访问文本则展开为今日
已做题数和历史日记录。所有按天统计都固定使用
Asia/Shanghai,也就是北京时间作为日切边界,不跟浏览器所在系统时区
漂移。本次 session 计数只存在于当前页面打开期间;每题 PB、上次 AC 和
每日 AC 摘要保存在当前浏览器练习存储中。每日摘要记录北京时间日期下的
去重 AC 题目、AC 提交次数、AC 总耗时、当日最快单题、首次 AC 时间和最后
AC 时间。计时面板需要给出对比反馈,例如今日新纪录、追平日记录、本题
PB、当日均速新高、近 7 日活跃和连续天数;同时用一个折叠的日统计入口
展示最近 14 个北京时间自然日,方便回看和对比。页面可以提供“重开本次”
和“重开本题”的手动口子,其中“重开本题”只重置当前 active timer。另有一个
不显眼、需要确认的“清本题记录”,只清当前题 PB 和上次 AC,不回滚每日统计。
日常刷题路径仍然是自动记录。计时面板还提供默认开启的“跳过 SQL”和
“跳过前端”本地路由开关;开启后,Option+J/Option+Down、
Option+K/Option+Up 的上下题跳转会跳过带数据库标签的 SQL 题,以及
官方模板只有 JavaScript/TypeScript 的纯前端题,但不会把这些题从列表、
搜索或手动点击里隐藏。
沉浸刷题流是一个默认关闭的本地开关,可以从
计时面板按钮或 Cmd+Option+F 切换;开启后,只有完整提交到力扣并返回
Accepted 才会按当前筛选/搜索顺序自动打开下一题;如果某个题型跳过开关
已开启,顺序流会在同一顺序里选择下一道不属于已跳过题型的题。这个自动
切题必须和手动打开题目一样,把题目标题、题面和编辑器一起框住;编辑器
获得焦点时不得立刻把标题或题面再次滚出视口。运行样例通过不会自动切题。
耐久练习事实必须写入 append-only 的 IndexedDB 事件日志,而不是反复整块
改写 localStorage JSON。事件日志按浏览器 origin 隔离,记录完整提交尝试、
样例运行尝试、Accepted 计时、手动做过/思考/熟练状态变化,以及清当前题
计时记录这些事实。页面打开时会把旧版 localStorage 里的进度、计时和提交
统计 JSON 迁移成稳定的 legacy snapshot 事件,只做一次;之后可见状态都从
事件日志重建。localStorage 只保留为这些 projection 的兼容缓存,以及代码
草稿、滚动位置、当前视图、路由开关、访问过链接样式这类天然属于 tab-local
或 last-write-wins 的状态。
因此多个标签页同时刷题时,每个标签页都追加自己的事实事件,不再重写同一个
大 JSON。某个标签页追加事件后,会通过 BroadcastChannel 广播轻量更新,并
同时写一个 storage pulse key 作为 fallback。其它已打开标签页收到通知后,
重新读取事件日志,重建进度、计时和提交统计,刷新可见题目行信号,并刷新
“猜你想练”浮层。如果 IndexedDB 不可用,页面才退回旧的单标签页
localStorage projection 行为;正常支持路径必须由事件日志支撑,并在多标签
页之间做到最终一致。
“猜你想练”也可以进入沉浸刷题流,但它不是列表顺序流。用户可以在“猜你想练”
浮层里启动推荐流,或用 Cmd+Option+Shift+F 直接启动;页面会先打开当前推荐
分最高的一题,并把流状态保持为“推荐流”。之后每次完整提交 Accepted,页面
都会用最新的本地提交、计时、人工状态和当前 session 疲劳重新计算“猜你想练”,
再打开新的最高推荐题,而不是打开页面上的下一行;这个自动推荐跳转也遵守
顺序流同样的标题、题面和编辑器框选规则。刚刚 AC 的题不会立刻被
推荐回自己;如果某个题型跳过开关已开启,对应题目会先从推荐候选队列里移除,
再选择最高推荐。若当前没有可推荐题,页面停留在当前题并给出状态提示。非 AC
提交和运行样例通过都不会推进推荐流。
页面还会记录当天的一遍过 AC 连击。这个连击按北京时间自然日计算,每天 00:00 自动归零;历史最高连击单独持久保存和展示。连击单位不是题目本身, 而是一次从官方默认模板或本地 fallback 默认模板开始的 fresh attempt。首次 打开没有草稿的题、手动重置当前题草稿、切换语言后重新生成默认模板、以及 北京时间日切把代码草稿清回默认模板,都会开启新的 fresh attempt。因此, 某道历史已经 AC 的题,只要编辑器重新回到默认模板,用户再从头写到 AC, 仍然可以再次计入当天连击。
fresh attempt 只有同时满足这些条件才会让当天一遍过连击加一:当前代码相对 默认模板有有效改动;这一轮没有任何官方样例运行失败;这一轮没有任何完整 提交失败;并且这一轮第一次完整提交返回 Accepted。运行样例不是必须步骤; 不跑样例直接完整提交 AC 也可以计入,只要此前没有样例失败。fresh attempt 里一旦样例运行失败或完整提交失败,当前当天连击立刻归零,并且这一轮之后 即使修到 AC 也不再补记连击。扩展未安装、登录失效、网络失败、请求超时、 以及其它没有拿到力扣最终判题结果的情况,不增加也不打断连击。同一轮已经 计入连击后,原代码重复提交、无改动提交、小改后再次 AC、或者同一轮后续 失败,都视为中立行为:不加连击,也不打断连击。想重新获得连击资格,必须 先回到默认模板开启新一轮。
一遍过连击 UI 应展示在计时面板里,并在当前编辑器的紧凑指标条里展示本轮 状态。编辑器内的状态需要区分“一遍过候选”、“本轮样例已错”、“本轮提交 已错”、“本轮已计入连击”和“重复提交不影响连击”。连击增加时,页面可以用 固定定位的背景烟花、光轨、纪录脉冲和随机鼓励文案做奖励反馈,但不得抢走 焦点、不得要求用户确认、不得阻塞继续输入,也不得改变页面布局。鼓励标题和 副标题必须使用练题 UI 同一套默认苹方优先文字栈,即使固定浮层是运行时动态 创建的,也不能掉回全站衬线字体。奖励强度应随普通连击、里程碑连击和刷新 最高纪录逐层升级;用户开启 reduced motion 时,应退化为更安静的静态提示, 而不是大量粒子动画。
成就墙共 99 枚成就,只统计本页发起的完整力扣提交,并且必须等力扣返回
Accepted 后才计入;
手动“做过”、“需思考”、“熟练”状态、运行样例通过、打开题目链接和历史力扣
提交记录都不计入成就。成就解锁事实也写入同一份 IndexedDB 事件日志,事件
类型为 achievement-unlocked;页面从真实提交、计时、题目标签和一遍过连击
投影出成就进度,再把已经达成但尚未记录的成就追加为解锁事件。成就入口放在
搜索栏后面,保持为一个紧凑按钮;hover、focus 或点击时展示游戏徽章墙。未
解锁的普通成就展示标题、进度和条件,隐藏成就展示为 ???,只给模糊提示,
解锁后才显示真实标题和说明。解锁反馈只能是非阻塞 toast 或按钮脉冲,不得
抢走编辑器焦点,不得改变题目列表布局。终局成就应覆盖全题册 AC、全难度
AC、全年连续 AC、百题日和专题全 AC 这类极高难度目标。
通过本页完整提交到力扣或运行官方示例时,页面还会写入一份独立的本地提交 统计。它不导入力扣历史提交记录,只记录这个功能上线后从本地编辑器发起的 动作。每道题会记录提交次数、Accepted 次数、提交出错次数、样例运行出错 次数、最近代码量、Accepted 耗时、Accepted 平均耗时,以及每 10 行非空代码 耗时。页面用一个紧凑的“猜你想练”入口承载 hover/focus 浮层,并把推荐排序 建模成浏览器本地的练习调度,而不是只看单一弱点分。
“猜你想练”的最终分仍截断到 0 到 100,但它由五个可解释分量合成: 到期复习、薄弱程度、题目价值、当前适配和疲劳惩罚。到期复习会为每道题 估计一个本地稳定度和可回忆率;完整 Accepted、连续 Accepted、样例通过和 人工“熟练”会提高稳定度,失败、耗时偏慢和人工“需思考”会降低稳定度。距离 上次 AC 越久,可回忆率越低,到期复习分越高;没有完整 Accepted 的题会被 当作尚未建立稳定度处理。薄弱程度继续使用缺少完整 Accepted、提交失败、 样例运行失败、按代码量归一后的 Accepted 耗时偏慢和人工“需思考”等信号; 提交失败强于样例失败,失败率做平滑,失败次数按边际递减增长。题目价值 来自 Top888 频率、Hot100、字节企业题库、最近字节 bucket、标签覆盖和相关 题网络、灵神题单覆盖,不让低价值冷门题只因为“不会”就长期压过高频核心题。当前适配会 根据当前打开题、共享标签、相关题关系和难度邻近度,优先推荐同路线迁移或 合理进阶。疲劳惩罚会降低今天已经 AC、当前 session 已经 AC、或与今天已练 标签高度重复的题,避免推荐流卡在同一类题里。
在按分数排序前,调度器会先把没有完整 Accepted 证据的 Hot100 题提升到 非 Hot100 候选之前;这些被提升的 Hot100 题内部仍然使用同一套调度分和 同分兜底排序。
这个调度器也支持冷启动:即使某题还没有本地提交记录,只要它本身频率高、 属于 Hot100、字节高频、标签覆盖价值高,或者被人工标记为“需思考”,也可以 进入候选队列。浮层展示排序靠前的题、最终练习分和主要原因;已提交过的题 仍会在题目行里显示紧凑信号。页尾有一个折叠说明解释五个分量、稳定度、 可回忆率、冷启动和同分兜底排序。分数最高的题会成为“猜你想练”,排序靠前 的题可以直接从浮层打开;浮层里也提供“开始推荐流”入口,用来把推荐流保持住。 这个排序只作为浏览器本地的启发式建议。
直接提交到力扣通过 extensions/leetcode-submit 里的 Chrome 扩展实现。
页面只通过 window.postMessage 为 run 和 submit 发送 titleSlug、
langSlug 和当前编辑器代码;run 还可以带上本地保存的补充用例。content
script 把请求转发给 extension background。background 负责持有力扣 cookie、
查询 questionEditorData、通过 interpret_solution 创建官方示例加补充
用例运行任务、向力扣中国区创建完整提交,并尽快把 LeetCode 返回的运行或
提交 ID 返回页面。页面随后用短 check 请求轮询扩展;扩展每次只查一次
/submissions/detail/{id}/check/ 并返回结构化状态,避免 Manifest V3
后台长时间等待导致消息通道断开。为了兼容已经加载的旧版 unpacked 扩展,
页面也会先接受初始 run 或 submit 响应里已经完成的结果,然后才发送
check。页面还会在练习编辑器打开时主动探测 login-status;这个响应会
带上扩展功能版本和 capability 列表,所以页面可以判断当前已加载的 unpacked
扩展是否是最新能力,并把缺失或过旧的安装引导到页面底部的安装说明。cookie
值不会发给页面 JavaScript,也不会存入仓库。如果扩展未安装、版本过旧或用户
未登录,页面只显示状态,本地编辑器仍然可用。运行样例结果区会展示实际发送给
力扣的用例输入,并根据 questionEditorData.metaData 拆成带参数名的逐个
case tab。运行结果返回后,每个 case 会在力扣暴露数组结果时展示提交代码的
实际输出、期望输出和 stdout。编译错误和运行错误不属于单个 case,仍放在
case tab 外展示。运行样例只有在力扣返回的所有 testcase 计数都通过时才算
通过。完整提交返回失败用例时,页面会在状态行下方展示失败用例、
实际输出、期望输出,以及编译或运行错误诊断,并把该失败用例保存为同题下次
运行样例的补充用例;如果同样归一化后的用例已经保存,则不会重复添加。补充
用例也可以由用户在已打开的答题区手动录入、查看、单条删除或整题清空。手动
录入和失败提交自动保存使用同一份归一化本地存储,只会随下一次运行样例一起
发送,不会随完整提交发送。补充
用例会在下一个北京时间自然日清空,所以每天练习都会重新从官方默认样例开始。
页面底部还提供常驻的 GitHub 仓库、扩展目录、最新扩展 ZIP、反馈 issue 和
页面规格链接。页脚下方必须保留舒适留白,链接行不能顶到页面结尾或视口边缘。
扩展安装说明默认折叠,讲清楚如何从 GitHub Release 包或本
仓库源码加载、更新和重新加载这个未打包的 Chrome 扩展;练习编辑器的扩展
状态区会直接链接到这段说明和稳定的 latest-release 下载地址。扩展发布 tag
命名为 leetcode-submit-v<manifest version>;推送这个 tag 后,发布流程会
把 extensions/leetcode-submit 打成 leetcode-submit.zip 和
leetcode-submit-<version>.zip 两个 Release 资产。Chrome 对这种非商店
扩展仍然按 unpacked extension 安装,所以安装说明必须写清楚:先下载 ZIP、
解压,再在 chrome://extensions 里选择解压后的文件夹;更新时覆盖本地
解压目录后,对这个已解压扩展点一次重新加载。
预览按钮包含思路、实现、标签和相关题。题面不作为 hover 触点,改为展示在
打开后的编辑器上方。思路/实现/标签预览可以通过 hover 临时查看,鼠标从
按钮自然移动到浮层内容时应保留浮层,离开浮层后再自动收起;也可以点击
固定展开,固定展开后点击预览外的空白区域或按 Escape 应收起。
实现预览用于承载 reference implementation
的面试展开顺序、最终参考代码、来源状态和追问。reference implementation
允许提交到这个 repo 并通过 GitHub Pages 公开展示。当前页面先同步最高频
题目中能抓到的最近通过提交;其余目标题会用公开、带来源、带授权标记的
reference implementation 补齐。实现预览优先展示 C++ 参考实现,并对 C++
代码做本地语法高亮。某题有多个主流面试解法时,按照推荐展开顺序展示多份
实现;如果公开来源本身已经拆成 Solution 1、Solution 2,则沿用这个顺序。
对于力扣本身不是 C++ 题型的行,例如 SQL、JavaScript、Shell 或 Pandas
练习题,不会伪装成 C++,而是展示与官方题型匹配的语言实现。
reference implementation 的覆盖率需要本地生成并审计。同步命令是
npm run sync:leetcode-implementations,它读取公开题解包并写入
src/data/leetcode-implementation-generated.ts。审计命令是
npm run check:leetcode-implementations,如果任何目标题没有实现引用、
有官方 C++ 模板的题没有 C++ 实现、或者实现里还残留 placeholder TODO,
审计都会失败。当前来源会在每份实现里单独记录:最近的个人 AC 提交、
Doocs LeetCode(CC-BY-SA-4.0)、kamyu104 LeetCode-Solutions(MIT),
以及少量用于补稀疏 LCP/LCCI 缺口的 generated-original 实现。每份外部
reference 都必须在 hover 卡片里保留来源链接、来源标题、授权标记、语言
和 provenance 标记。
练习状态
站点是静态页面,所以不能保存服务端做题次数。练习状态保存在当前浏览器的 本地存储里:
- 做过表示已经尝试过这道题。
- 需思考表示这道题应该回看。
- 熟练表示当前已经比较顺手。
点击过的题目链接会使用浏览器自带的 visited 样式,也会额外写入本地访问 标记,所以同一个浏览器配置里可以继续看出哪些题点过。
预览契约
题面面板使用中文题面里抽出的短文本。题面中类似提示词的样板句会在渲染前 移除。
思路预览分成两层:
- 基于标签生成的通用检查点,并给出简短解答;
- 公开来源可核实的公司追问,并给出简短解答、公司和来源链接。
公司追问列表故意保持保守。它不表示其他公司没有问过同一个追问,只表示 当前能在公开页面里核实到这些来源。