广告:Codex Token 低价中转站稳定接口 · 快速接入 · 开发者备用通道
Engineering article

LeetCode刷题顺序推荐 | 模板总结

我见过太多人刷题直接从简单题开始,结果到中等题就卡住了。LeetCode刷题顺序真的得讲究,不能盲目乱冲。我见过有的兄弟前100题都做完了,死活过不了中等题,其实是因为没有按正确的顺序来。我之前是按“数据结构 + 算法 + 题型分类”这样的路径走的,效率高了很多。数据结构优先,比如数组、链表、树、图这些,先把它们的遍历、操作、基本问题搞明白。再做算法题,先掌

LeetCode刷题顺序推荐 | 模板总结
配图来源于网络和AI生成,仅供参考。
我见过太多人刷题直接从简单题开始,结果到中等题就卡住了。LeetCode刷题顺序真的得讲究,不能盲目乱冲。我见过有的兄弟前100题都做完了,死活过不了中等题,其实是因为没有按正确的顺序来。我之前是按“数据结构 + 算法 + 题型分类”这样的路径走的,效率高了很多。数据结构优先,比如数组、链表、树、图这些,先把它们的遍历、操作、基本问题搞明白。再做算法题,先掌握二分查找、贪心、递归、动态规划这些核心思路,再逐步往更复杂的题目进发。中等题要分题型,比如字符串处理、排序、搜索、模拟、数学计算这些,得一个一个类型来。难题别急着做,先练熟练度,再进阶。

我之前踩的坑是,没弄清题型之间的关联,导致刷题时重复劳动。比如动态规划和回溯,容易混淆。还有问题的边界条件,比如空数组、重复元素、边界值,这些很容易被忽略。我见过有人做题的时候,把题目理解错了,结果代码写得再好也没用。这个问题必须重视,我见过很多兄弟因为理解错题意,花了几个小时也没拿到正确结果。刷题要先看问题描述,再看样例输入输出,最后才看提示。我之前是直接看提示,结果根本没搞清楚问题本质,反而浪费了时间。要在理解题意上花时间,别怕麻烦。

刷题要结合模板,别自己瞎造。常见的模板有双指针、滑动窗口、深度优先搜索、广度优先搜索、二分查找、贪心策略、动态规划、回溯这类。我之前是看题就自己想解法,结果写出来的代码和别人比起来,效率低得离谱。现在我习惯先看题型再选模板。比如字符串类的题,常见的是KMP、Rabin-Karp、Z-Algorithm这些,得熟悉它们的用法。数组类的题,比如前缀和、差分数组、位操作这些模板,我见过有人用得特别溜。比如前缀和,用数组保存前i项的和,这样查询区间和的时候就能O(1)完成。差分数组用来处理区间增减,效率很高,我之前在处理某些题目时,用差分数组把时间从O(n)降到了O(1)。

我见过有人在刷题时,代码写得又慢又丑,结果被别人嘲笑。这其实是技术路径的问题,不是刷题数量的问题。写代码要遵循规范,比如变量命名、函数结构、注释习惯。我之前就是用变量名全大写,结果导致代码可读性很差,还容易出错。现在我统一用小驼峰或者大驼峰,比如isPalindrome、findSubString这种。还有函数的参数结构,比如用结构体或者字典传参数,这样代码才清晰。我见过有人写代码,直接把所有参数塞进一个字典,结果逻辑混乱,调用起来特别麻烦。规范代码,才能提高效率。

刷题过程中,调试和测试也是关键。我之前写完代码就直接提交,结果经常出错。现在习惯在本地环境测试,比如用Python写完代码,直接在IDE里运行测试用例。还有测试用例的生成方法,比如用随机数生成器生成测试数据,这样能覆盖更多的边界情况。我见过有人用单元测试的方式,把每个函数单独测试,避免整体出错。还有调试技巧,比如用print或者log输出中间结果,这样能快速定位问题。我之前就是靠这种办法,把一个死循环的问题快速找出来。测试和调试是刷题不可或缺的一部分。

技术参考
▌ 技术引导

我见过太多人刷题直接从简单题开始,结果到中等题就卡住了。LeetCode刷题顺序真的得讲究,不能盲目乱冲。我之前是按“数据结构 + 算法 + 题型分类”这样的路径走的,效率高了很多。数据结构优先,比如数组、链表、树、图这些,先把它们的遍历、操作、基本问题搞明白。再做算法题,先掌握二分查找、贪心、递归、动态规划这些核心思路,再逐步往更复杂的题目进发。中等题要分题型,比如字符串处理、排序、搜索、模拟、数学计算这些,得一个一个类型来。难题别急着做,先练熟练度,再进阶。

我之前踩的坑是,没弄清题型之间的关联,导致刷题时重复劳动。比如动态规划和回溯,容易混淆。还有问题的边界条件,比如空数组、重复元素、边界值,这些很容易被忽略。我见过有人做题的时候,把题目理解错了,结果代码写得再好也没用。这个问题必须重视,我见过很多兄弟因为理解错题意,花了几个小时也没拿到正确结果。刷题要先看问题描述,再看样例输入输出,最后才看提示。我之前是直接看提示,结果根本没搞清楚问题本质,反而浪费了时间。要在理解题意上花时间,别怕麻烦。

刷题要结合模板,别自己瞎造。常见的模板有双指针、滑动窗口、深度优先搜索、广度优先搜索、二分查找、贪心策略、动态规划、回溯这类。我之前是看题就自己想解法,结果写出来的代码和别人比起来,效率低得离谱。现在我习惯先看题型再选模板。比如字符串类的题,常见的是KMP、Rabin-Karp、Z-Algorithm这些,得熟悉它们的用法。数组类的题,比如前缀和、差分数组、位操作这些模板,我见过有人用得特别溜。比如前缀和,用数组保存前i项的和,这样查询区间和的时候就能O(1)完成。差分数组用来处理区间增减,效率很高,我之前在处理某些题目时,用差分数组把时间从O(n)降到了O(1)。

我见过有人在刷题时,代码写得又慢又丑,结果被别人嘲笑。这其实是技术路径的问题,不是刷题数量的问题。写代码要遵循规范,比如变量命名、函数结构、注释习惯。我之前就是用变量名全大写,结果导致代码可读性很差,还容易出错。现在我统一用小驼峰或者大驼峰,比如isPalindrome、findSubString这种。还有函数的参数结构,比如用结构体或者字典传参数,这样代码才清晰。我见过有人写代码,直接把所有参数塞进一个字典,结果逻辑混乱,调用起来特别麻烦。规范代码,才能提高效率。

刷题过程中,调试和测试也是关键。我之前写完代码就直接提交,结果经常出错。现在习惯在本地环境测试,比如用Python写完代码,直接在IDE里运行测试用例。还有测试用例的生成方法,比如用随机数生成器生成测试数据,这样能覆盖更多的边界情况。我见过有人用单元测试的方式,把每个函数单独测试,避免整体出错。还有调试技巧,比如用print或者log输出中间结果,这样能快速定位问题。我之前就是靠这种办法,把一个死循环的问题快速找出来。测试和调试是刷题不可或缺的一部分。

▌ 技术参考

刷题顺序必须基于知识结构,别瞎冲。数据结构是基础,建议从数组、链表、栈、队列、哈希表、树、图这些开始。别一开始就做题,先理解它们的特性,比如数组的连续性、链表的灵活性、树的递归结构、图的边处理。我之前做树的题目时,没搞懂前序、中序、后序遍历的区别,直接写代码,结果根本过不了测试。建议先画图理解,再写代码。比如数组的遍历,要区分不同增量,比如i += 1、i = 2,这些细节容易出错。链表操作要记住头结点和尾结点的处理方式,避免空指针异常。

刷题不能只看答案,得自己动手写。我之前是看答案再写,结果代码写出来总有一些细节没注意。比如循环条件、边界处理、返回值判断。这些容易被忽略的地方,往往就是卡题的关键。我见过有人做题时,总是忘记循环终止条件,导致无限循环。还有人没考虑空的情况,比如空字符串、空数组,结果代码直接炸。建议刷题时,先自己写一遍,再看答案。否则你会发现,自己写的代码和官方解法差距很大,特别是时间复杂度和空间复杂度。比如用哈希表来去重,别直接用set,得自己实现哈希逻辑,这样才更深入。

刷题时要关注题型,比如字符串类、数组类、树类、图类、动态规划类、贪心类,每类都要有代表性题目。我之前是混着刷,导致效率低下。比如字符串类,建议从子串、子序列、匹配、转换这些方向入手。比如KMP算法,要理解next数组的构造方法,别直接套用模板。数组类建议从排序、查找、双指针、滑动窗口这些方向入手。比如滑动窗口,要理解窗口如何滑动、如何更新、如何记录结果。我之前用滑动窗口做题,总是没弄清楚窗口的移动条件,导致算法错误。题型分类是刷题的效率保障。

动态规划是高频考点,必须掌握。建议从基础题入手,比如斐波那契数列、爬楼梯、背包问题,这些能帮助理解状态转移方程。动态规划的核心是状态定义和状态转移。我之前总是在状态定义上出错,比如把dp[i]写成dp[i+1],导致整个结果错误。还有状态转移方程,得理解递推逻辑,比如dp[i] = max(dp[i-1], dp[i-2]+nums[i])。别急着上手复杂题,先练熟基本思路。动态规划的优化方法比如空间优化、滚动数组,得在熟练基础题后慢慢掌握。我之前用滚动数组优化代码,结果反而更复杂,搞错了索引。

回溯算法是另一个难点,必须通过刷题掌握。建议从子集、组合、排列、分割这些题目开始。回溯的核心是递归和剪枝。我之前做回溯题时,没搞清楚剪枝的条件,导致时间超限。比如在子集问题中,如果数组中有重复元素,必须先排序再剪枝,否则会重复计算。回溯的模板是固定的,先递归处理,再回退。我见过有人写回溯代码时,忘记回退,导致结果错误。回溯和动态规划都属于递归问题,但处理方式不同,必须区分开。

二分查找是经典算法,必须理解其原理。别以为数组有序就能用,得看是否有重复、是否允许边界值。我之前用二分查找处理一个有序数组,忘记处理重复值,导致死循环。二分查找的核心是不断缩小搜索范围,直到找到目标或者确定不存在。参数要传左边界和右边界,比如left = 0, right = len(nums) - 1。还有循环条件,是while left <= right,而不是left < right。写二分查找时,要关注mid的计算方式,比如mid = (left + right) // 2,或者mid = left + (right - left) // 2。后者能避免整数溢出问题,特别是处理大数组时。

贪心算法的思路是局部最优解,但必须理解它的适用条件。比如活动选择问题、硬币找零、跳跃游戏这些,都是贪心的经典题型。我之前做跳跃游戏时,没理解贪心选择的条件,直接暴力搜索,效率低下。贪心算法的关键是证明每一步都是最优的,否则无法保证全局最优。比如硬币找零问题,只有在硬币面额满足特定条件时,贪心才有效。建议先掌握贪心的基本思想,再刷题。比如每次选择当前可选的最优解,然后递归处理剩余部分。写代码时要关注条件判断,别漏掉任何细节。

图算法是高频考点,建议从DFS、BFS、拓扑排序这些开始。我之前做图的题目时,总是忘记初始化访问数组,导致死循环。图的存储方式影响算法效率,比如邻接矩阵和邻接表各有优劣。邻接矩阵适合稠密图,邻接表适合稀疏图。DFS和BFS的区别在于是否优先处理深度还是广度。我见过有人用DFS做BFS题,导致超时。图的遍历必须处理节点的访问状态,比如用一个布尔数组标记是否访问过。拓扑排序要理解入度和出度的计算方式,别搞混顺序。

字符串处理是另一个重点,建议从字符统计、子串匹配、字符串转换这些入手。我之前做字符串匹配题时,直接暴力解法,效率低下。字符串拼接要注意空间复杂度,比如用字符串拼接时,频繁操作会导致高时间复杂度。建议使用可变字符串或者StringBuilder来优化。比如Python中直接字符串拼接会生成太多中间对象,效率差。字符串处理的难点在于边界和长度,比如空字符串、奇偶长度、重复字符。我见过有人在处理字符串的时候,没考虑空的情况,直接抛异常,结果代码被拒绝。

数学计算题涉及数论、组合数学、排列组合等,建议从基础开始。我之前做数学题时,没理解时间复杂度,直接暴力枚举。比如质因数分解,暴力法效率太低,必须用埃拉托斯特尼筛法。还有最大公约数、最小公倍数、排列组合这些,得掌握快速计算方法。数学题的关键是找出规律,比如斐波那契数列、阶乘、幂等。我见过有人做斐波那契数列题时,没用动态规划,直接递归,结果超时。要利用递推公式和数学规律,提高效率。

模拟题是考察代码逻辑的,建议从简单的流程模拟开始。我之前做模拟题时,总是写太多分支判断,导致代码复杂。模拟题的关键是按步骤处理,比如处理字符串、处理循环、处理条件判断。我见过有人在模拟题中,因为循环条件写错,导致结果错误。模拟题的基础是逻辑清晰,不要求复杂算法。比如处理栈模拟,得理解push和pop的顺序。写模拟题时,尽量用结构化的方式,比如用队列、栈、数组等,别自己造轮子。

并查集是处理连通性问题的经典数据结构,建议从基础题目入手。我之前做并查集问题时,没理解路径压缩和按秩合并,导致效率低下。并查集的核心是Find和Union两个操作,必须优化。比如Find函数要实现路径压缩,避免树的高度过高。Union函数要按秩合并,保持树的平衡。我见过有人写的并查集代码,Find函数没做压缩,导致时间复杂度很高。并查集适用于图的连通性、集合合并、元素查找等场景,但不适用于动态操作,比如删除元素。

位运算题涉及位操作、位掩码、位移、异或等,建议从基础位操作题开始。我之前做位运算题时,没理解位掩码的使用,导致代码效率差。位运算的核心是利用二进制特性,比如异或能找出唯一出现的数字,位移能快速计算幂。我见过有人用位运算处理整数时,没考虑负数的情况,导致结果错误。位运算的效率非常高,但必须理解其原理,否则容易出错。比如找出一个数组中唯一出现两次的数字,可以用异或操作,最终结果就是那个唯一的数字。

红黑树和平衡树是高级数据结构,建议在掌握基础后才深入。我之前做平衡树题时,没理解平衡的条件,导致代码错误。红黑树的性质包括颜色、平衡因子、旋转等,必须熟悉其定义。平衡树的核心是保持树的高度平衡,避免极端情况导致效率下降。我见过有人做平衡树问题时,没处理旋转逻辑,导致树结构错误。红黑树适用于需要高效插入、删除、查找的场景,但实现复杂度高,不适合新手。建议先掌握二叉搜索树,再进阶到红黑树。

链表操作是高频考点,建议从基本操作开始。我之前做链表题时,总是忘记处理头结点,导致指针错误。链表操作包括插入、删除、遍历、反转、排序等,这些必须熟练掌握。比如链表反转,要记录前驱节点,避免断链。我见过有人在反转链表时,没处理前驱节点,导致链表断裂。链表的指针操作是关键,别急着写复杂逻辑,先处理基本结构。链表排序可以使用归并排序,效率较高。我之前用冒泡排序处理链表,结果超时。

多线程是进阶话题,建议在掌握基础后才深入。我之前做多线程题时,没理解线程同步机制,导致结果错误。多线程的核心是资源竞争、互斥、同步。比如用锁来控制访问共享资源,避免数据不一致。我见过有人用线程池执行任务时,没处理任务的顺序,导致结果错乱。多线程的效率高,但也容易出错。建议先掌握线程的基本操作,再做同步和异步题。比如用CompletableFuture来处理异步任务,效率很高。多线程适用于需要并行处理的场景,但不适用于I/O密集型任务。