大家好,我是前端西瓜哥,今天说说我在 LeetCode 刷算法题学到的一些套路。
判断解法
对于判断解法,首先你要掌握对应的解法套路,以后发现类似的特征时,可能就是对应的解法套路。
- 如果说明传入的参数规模较小,比如
1<=nums.length<=100
,说明数据大一些都会导致耗时直线上升。潜台词:这是一道动态规划或回溯题。 - 如果给的是有序数组,考虑用二分查找。
- 如果是岛屿问题,通常用 Flood fill 解法。
- 如果要求你实现一个类,然后调用类的方法求指定范围内的数据,通常用到 前缀和 的技巧。
- ...
空间复杂度
如果要求空间复杂度为 O(1),当发现用几个变量无法解决时,大概率 要用传入的数据自身来临时保存数据。
比如题目:71.矩阵置零 就需要用传入的二维数组的首行和首列,来存储某行或某列是否需要填充为 0 的信息。
合适的数据结构
- 如果提供的数据有范围,优先考虑用数组替代哈希表。因为 数组的存取效率更高。哈希表有一个函数映射计算的过程,而且当映射的索引冲突太多时,时间复杂度会下降为 O(n)。如果要保存的是布尔值,可以用位来表示布尔值数组,极致地压缩空间。
- 像 JS 这种缺乏底层数据结构的语言,我们常常会让数组充当一些数据结构,比如队列。但数组实现的队列效率很低,可以手写个双链表实现的队列备份起来,用到的时候复制粘贴。当然实际刷题时二者细微的耗时区别其实并不大。
时间超时的一些可能原因
- 先看看是不是一个数据规模很大的测试用例导致的。如果是,可能是使用了非常低效的算法,或者没有做剪枝。
- 递归跳出条件有问题或者没有剪枝,导致了非常深的递归。当然可能会出现一个栈溢出的错误,就更能确定是这个问题了。
其他
- 一开始做题时使用原生的 for 循环,而不是一些自带的封装的迭代方法(如 forEach),因为可能需要你在循环过程中结束循环,或者用 return 直接返回结果。
- 一些要返回一个新的链表或二叉树的题目,请务必处理好引用类型的属性,尤其是最后一个节点的 next 要设置为 null,否则可能会出现环。
- 有些题目纯粹是数学题,或者是找规律,没有套路可言,十分钟想不出来直接看题解。
- 可以尝试用不提供代码高亮的编辑器写代码,因为面试时面试官可能会让你用记事本写,或者手写。