news 2026/10/8 8:12:02

LogicStack-LeetCode 模拟类题解地图:266 道模拟题的识别方法、通用套路与源码精讲

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LogicStack-LeetCode 模拟类题解地图:266 道模拟题的识别方法、通用套路与源码精讲
  • 教程
  • 文档

【免费下载链接】LogicStack-LeetCode

公众号「宫水三叶的刷题日记」刷穿 LeetCode 系列文章源码

项目地址:https://gitcode.com/gh_mirrors/lo/LogicStack-LeetCode
点击查看免费下载

模拟(Simulation)是 LeetCode 中覆盖面最广、出现频率最高的题型之一:从字符串处理、矩阵遍历到游戏规则、状态机推演,凡是「按照题意把过程一步步走完」的题目,几乎都可以归类为模拟。本文以「宫水三叶的刷题日记」开源仓库 LogicStack-LeetCode 中的 Index/模拟.md 索引为骨架,系统梳理该仓库收录的 266+ 道模拟类题目,并结合仓库内多篇代表性题解源码,提炼出模拟题的通用识别方法、分类体系与实战套路,帮助你建立一套可复用的「模拟题做题框架」。

一、什么是模拟题:先学会「认出」它

模拟题的核心特征非常朴素:题目描述即算法。出题人把某个过程(一个游戏、一次遍历、一组规则、一段文本处理)用自然语言完整描述出来,解题者只需要忠实地把这个过程翻译成代码,而不需要引入贪心、DP 等额外的算法优化。

在 LogicStack-LeetCode 仓库中,每篇题解都会在开头用Tag : 「模拟」标注题型,例如 495. 提莫攻击(简单) 标注Tag : 「模拟」,1583. 统计不开心的朋友(中等) 则标注Tag : 「哈希表」、「模拟」——后者说明「模拟」常与哈希表、双指针、栈、队列等基础数据结构组合出现。

识别模拟题的三个典型信号:

信号典型表现示例题
过程化描述题目给出完整步骤、回合、时间线495. 提莫攻击、1503. 所有蚂蚁掉下来前的最后一刻
规则即约束按给定的规则逐项判断、计数412. Fizz Buzz、299. 猜数字游戏
状态推进从初始状态出发,按规则一步步推进38. 外观数列、1104. 二叉树寻路

二、读懂仓库的模拟题索引:结构与用法

Index/模拟.md是仓库中「模拟」这一主题的导航总表,采用四列表格组织全部收录题目:

  • 题目列:链接到 LeetCode 原题,便于直接查看题目描述与提交评测;
  • 题解列:链接到宫水三叶在 LeetCode 上的对应题解,涵盖完整思路推导与多语言代码;
  • 难度列:简单 / 中等 / 困难,用于规划练习节奏;
  • 推荐指数列:以 🤩 数量(1~5 个)标注推荐优先级,🤩🤩🤩🤩🤩 表示强烈推荐优先练习。

从索引可见,模拟题覆盖了从简单到困难的全难度梯度:

  • 简单题(如 1. 两数之和、7. 整数反转、66. 加一、495. 提莫攻击)适合作为入门热身;
  • 中难题(如 54. 螺旋矩阵、65. 有效数字、591. 标签验证器、1001. 网格照明)则要求更精细的状态设计,往往需要配合哈希表、栈、双指针等工具。

推荐的练习路径是:先刷推荐指数 ≥ 🤩🤩🤩🤩 的简单题建立手感,再挑战同指数的中难题,最后用困难题检验对「过程建模」的掌控力。

三、模拟题的通用方法论:来自源码的四步框架

对比仓库中多篇题解,可以提炼出模拟题的通用四步框架:

3.1 明确状态与哨兵值

模拟题的第一步是定义「需要维护的状态」。以 495. 提莫攻击 为例,核心状态是「上一次攻击的结束时间点last」。题解中特别强调了一个关键细节:last初始化为-1(哨兵值),而非0,目的是保证当timeSeries[0] = 0时第 0 秒也能被正常计数:

int ans = 0, last = -1; for (int s : timeSeries) { int e = s + duration - 1; ans += last < s ? duration : e - last; last = e; }

这个哨兵设计的思路在模拟题中极其常见——边界状态(如第一次操作、空输入、起点为 0)往往需要专门处理,否则会产生经典的「差一错误」。

3.2 按区间/阶段拆分过程

当过程存在「重叠」或「分段」时,用区间视角拆分。提莫攻击题的核心洞见在于:若两次攻击不重合(last < s),本轮贡献完整的duration;若重合(last >= s),本轮只贡献增量e - last,相当于一次轻量级的区间合并。整体复杂度为 O(n) 时间、O(1) 空间。

3.3 建立索引/映射加速规则判断

当模拟过程需要频繁查询「两个对象的相对关系」时,预处理一张映射表是标准做法。以 1583. 统计不开心的朋友 为例:preferences[i]本身按亲密度从高到低排列,题解利用下标将其转换为「亲密度得分」map[i][preferences[i][j]] = n - j(得分越大越亲密),然后对每一对配对(x, y),遍历所有其他配对(u, v),检查是否存在「x 更喜欢 u 且 u 更喜欢 x」或「x 更喜欢 v 且 v 更喜欢 x」的互选背叛关系:

boolean check(int x, int y, int u, int v) { Map<Integer, Integer> xmap = map.get(x), umap = map.get(u); Map<Integer, Integer> vmap = map.get(v); if (xmap.get(u) > xmap.get(y) && umap.get(x) > umap.get(v)) return true; if (xmap.get(v) > xmap.get(y) && vmap.get(x) > vmap.get(u)) return true; return false; }

题解同时给出两种实现:哈希表套哈希表(P1)与二维数组(P2),并指出在 n ≤ 500 的数据范围内二维数组充当哈希表完全可行——这提示我们:模拟题的存储结构选择应服从数据范围,不必一味追求复杂结构。

3.4 处理多语言实现的一致性

仓库题解几乎每篇都同时给出 Java / C++ / Python / TypeScript 实现,且各语言逻辑完全一致。例如外观数列题中「双指针求连续段」在四种语言中结构相同,仅语法差异。这意味着你可以把仓库当作「多语言对照表」:先看懂任意一种语言的思路,再对照翻译成自己熟悉或需要练习的语言。

四、按题材拆解:五类高频模拟题精讲

将索引中的 266+ 道题按题材归类,可以得到五类高频模拟场景,每类都有可复用的套路。

4.1 字符串模拟:逐字符 + 双指针

字符串模拟是数量最多的一类,代表题包括 38. 外观数列、65. 有效数字、468. 验证IP地址、71. 简化路径、8. 字符串转换整数 (atoi)(中等).md)。

以 38. 外观数列 为例,题解给出「从ans = "1"出发逐项递推,用双指针求连续段长度」的经典写法:

String ans = "1"; for (int i = 2; i <= n; i++) { String cur = ""; int m = ans.length(); for (int j = 0; j < m; ) { int k = j + 1; while (k < m && ans.charAt(j) == ans.charAt(k)) k++; int cnt = k - j; cur += cnt + "" + ans.charAt(j); j = k; } ans = cur; }

其套路是:外层迭代阶段,内层双指针切分连续段,段内统计、段尾跳跃。这一模式同样适用于 443. 压缩字符串、1047. 删除字符串中的所有相邻重复项 等题。

4.2 矩阵模拟:按形状 / 按方向

矩阵类模拟题考察「坐标推进」能力,代表题有 54. 螺旋矩阵、59. 螺旋矩阵 II、867. 转置矩阵、1260. 二维网格迁移、1706. 球会落何处。

  1. 螺旋矩阵 的题解给出「按圈模拟」的思路:用左上角(x1, y1)与右下角(x2, y2)框定当前圈,按「上边 → 右边 → 下边 → 左边」四条边遍历,随后两个角点同时向中心收缩一圈,递归执行;并处理两个退化情况——只有一行(x1 == x2)按行走、只有一列(y1 == y2)按列走。这种「形状驱动」的模拟比维护方向数组 + 转向标志的写法更直观、不易出错,是矩阵遍历题的优选模板。

另一种矩阵模拟思路是「状态驱动」,可参考 1706. 球会落何处:对每一列的球,根据当前格子的挡板方向与下一格子的挡板方向判断能否继续下落,模拟整条下落路径。

4.3 数学模拟:按公式 / 按周期

当过程背后存在可推导的数学规律时,模拟与数学推导常可互相转化。索引中 166. 分数到小数、168. Excel表列名称、171. Excel表列序号、400. 第 N 位数字、1185. 一周中的第几天 均属此类。典型技巧包括:取模定位周期、进制转换(如 Excel 列名的 26 进制映射)、长除法记录余数判断循环节等。

4.4 游戏 / 规则模拟:忠实翻译规则

游戏类模拟题强调「严格按规则逐回合推进」,代表题有 412. Fizz Buzz、682. 棒球比赛、1823. 找出游戏的获胜者、2069. 模拟行走机器人 II、794. 有效的井字游戏。这类题目的难点往往不在过程本身,而在于把自然语言规则翻译成精确的边界条件——建议先写伪代码列出所有规则分支,再落成代码。

4.5 数据结构模拟:选对容器

部分模拟题需要借助栈、队列、哈希表等容器来承载过程,代表题有 20. 有效的括号、150. 逆波兰表达式求值、385. 迷你语法分析器、636. 函数的独占时间、591. 标签验证器。容器选择的关键是匹配过程的访问模式:后进先出用栈、先进先出用队列、随机/频繁查询用哈希表或字典树。

五、从索引到源码:如何在本仓库高效刷模拟题

LogicStack-LeetCode 仓库的目录结构按题号区间组织(如LeetCode/491-500/、LeetCode/1701-1710/),每篇题解文件以「题号. 题名(难度).md」命名,与索引文档一一对应。推荐的刷题工作流:

  1. 按推荐指数筛选:在 Index/模拟.md 中按难度 + 🤩 数量挑选目标题,优先覆盖各题材的代表题;
  2. 先读题解正文:每篇题解均包含完整的题目描述、示例、提示(数据范围)、核心思路推导与多语言代码(Java / C++ / Python / TypeScript),并附时间复杂度与空间复杂度分析;
  3. 对照多语言实现:利用同题多语言代码对照理解,或直接摘抄为本地练习的起点;
  4. 按主题回看归类:索引同时关联了仓库中其他主题索引(如 Index/哈希表.md、Index/双指针.md、Index/栈.md),同一道题往往同时挂在多个主题下,刷完模拟主题后,可以顺藤摸瓜串起相关联的算法主题,形成知识网络。

六、总结

模拟题是算法学习中性价比极高的题材:它不要求先掌握高深的算法理论,却对「把自然语言翻译成精确代码」的能力提出扎实要求。借助 Index/模拟.md 这份覆盖 266+ 道题的索引地图,你可以按难度、按题材、按推荐指数系统练习;配合仓库内每篇题解的多语言源码与复杂度分析,既能快速入门,也能在「字符串双指针」「矩阵按圈遍历」「哈希映射预处理」等通用套路上建立肌肉记忆,为后续学习 DP、图论等更复杂的算法主题打下坚实的「忠实模拟」基础。

  • 教程
  • 文档

【免费下载链接】LogicStack-LeetCode

公众号「宫水三叶的刷题日记」刷穿 LeetCode 系列文章源码

项目地址:https://gitcode.com/gh_mirrors/lo/LogicStack-LeetCode
点击查看免费下载

相关推荐

上一篇:当笔记从"收藏"变成"网络":一套开源Obsidian模板的知识管理改造全记录
下一篇:一键解决内存占用过高:MemReduct实测能释放10%-50%的Windows内存清理工具

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 8:08:14

Claude的“外置大脑”:用claude-mem实现跨会话持久记忆

Claude 用久了&#xff0c;大家应该都有同一个磨人的体验&#xff1a;开一个新对话窗口&#xff0c;它就“失忆”了。明明上一个 session 里已经把技术方案、命名规范、部署链路聊得清清楚楚&#xff0c;换一个窗口全部归零&#xff0c;又得从“我们之前讨论过的那件事……”开…

作者头像 李华
网站建设 2026/10/8 8:07:00

编辑器上下文模式实战:用符号树与LSP终结长文件迷失

前阵子我接手一个维护了快七年的老服务&#xff0c;业务逻辑倒不算难&#xff0c;真正的敌人是文件长度。一个核心类 800 多行&#xff0c;方法之间相互调用&#xff0c;我经常滚到屏幕中间就忘了自己是在类里还是已经在某个私有方法里&#xff0c;debug 到一半才发现改动放错了…

作者头像 李华
网站建设 2026/10/8 8:06:37

微信小程序+Java互助学习系统毕设:从技术选型到部署答辩完整指南

简介&#xff1a;这份资源是面向高校计算机相关专业学生与Java初学者的一套互助学习平台毕业设计完整方案&#xff0c;采用微信小程序前端搭配Java后端与MySQL数据库&#xff0c;适合作为毕业设计、课程设计或全栈入门练手项目。压缩包共1306个文件&#xff0c;约25.37MB&#…

作者头像 李华