我是从 2019 年 10 月开始固定刷题的,目前已经完成 464/1715 题目了,大部分题目的所有可能解法都一一仔细研究了下,所以你看我的提交量达到了 1285/1871。首先,99% 的题目我都用 JavaScript 写了一遍,其他有些偷懒的就用 Python 或 Java 写了。
目前已完成题目的比例是 easy/medium/hard 是 30%/55%/15% 左右:
另外我最近的 LeetCode 比赛的成绩是:
鉴于此,个人觉得有必要和大家分享下关于用 JavaScript 在 LeetCode 中比赛的经验。
目前来讲,大部分前端一直对基础的算法或者其他计算机科学知识处于冷落状态,原因可能有很多,但本质原因还是不能立刻获得回馈而已(也就是我花那么多时间学这些基础的东西,但是却不能立刻得到好处)。但我认为这些东西你迟早得补回来,就像现在的前端方向一直在补原来的课一样。
回归到主题,我是从瀑布流那篇文章了解到晨曦的,当时觉得他非常有想法,学习算法的思路也很高效(理论与实践相结合,其实也算是费曼学习法的运用)。很多人学习算法会进入过于理论的地步,这个时候你会学得很沮丧,后面就会进入放弃和自我怀疑的阶段。我因为那篇文章加了晨曦的微信和 LeetCode 好友,简单聊了下关于 LeetCode 的事。在我看来,光从 LeetCode 的时间线上就可以知道晨曦是个非常坚持的人。
最开始,大家就按照晨曦的提纲进行刷题学习就好了。那么本篇文章的目的是什么呢?主要是提供一些经验来帮助你加深对于 LeetCode学习(类似于初级到中级)。
正文
–
首先,目前国内大厂已经开始趋向于国外大厂,在面试中算法的比重越来越大。尽管历来这些计算机科学的基础在前端中考察会比较少(校招和社招都比较少,但由于校招大家实际项目经验普遍不太丰富,所以校招这些基础又会相对社招多一些)。
对于大部分都有志于进入国内大厂(国外大厂算法无论前后端都是必考项),算法一定是会成为你的“木板”之一的。
首先,我得申明 。
上面的公式是什么意思呢?LeetCode 中大部分题目都是可以在训练后做出来的,难度其实并不算很大,尽管这段时间有几场比赛开始有出 acm 原题的趋势,但是相比于原题,题目的数据规模都要小很多,这也就是意味着我们可以用更加低效、简单的解法来解决。这也就意味着你没有必要产生畏难心理,你换个思路思考下,又不需要你去发明一个算法,只是要你用别人发明的算法解题而已。在我看来,大部分人可以在规律的 3-6 个月训练达到不错的水平(每天抽出1-2小时)。
刷算法的好处
-
个人认为算法是程序的基石,是所有开发者都得掌握的东西,因为无论是前端工程师还是后端工程师,你都首先得是一个工程师。
-
当然是立刻能得到好处的,也就是面试导向,就像小厂的想去国内大厂,国内大厂的想去国外大厂。而算法题算是第一个敲门砖。
-
这一点是我个人最喜欢的,锻炼我们的思维能力。每一场周赛的1个半小时,都是你大脑高速运转的时候,你需要在这段时间里面想出解题思路,并且能够考虑所有的边界情况,写出 bug free 的代码(facebook 的题目需要你的代码直接 bug free)。每次比赛时都是高度集中的状态,比完赛后感觉特别的爽。
-
让你更加谦虚。在你翘尾巴的时候给你一巴掌,让你继续学习。每次看到比赛后前十名的比赛完成时间,我就会知道距离这群人差的还远呢。
下面给出我解题的一般步骤,该步骤基本通用于面试和比赛。
做题第一步: 读题
做一道 LeetCode 题目的第一步就是阅读题目内容和数据规模,这里的数据规模有点类似于数学题中的前提条件。通常来讲,题目的数据规模基本就可以告诉你算法时间复杂度的可选范围,也就意味着你大概可以用哪种解法。
通常来讲,我们会把 1GHZ cpu 1s 作为基准值,这一般表示着 cpu 每秒钟可以进行 10 的 9 次方浮点数运算,而你的算法每个 test 运算时间理论上最好不要超过 1 秒。如果你的估算超过了 1 秒,这往往意味着会超时(但是需要注意的是,我们在面试时这种解法仍然需要向面试官表达出来,因为尽管不是最优的解法,但是至少我是解答出来了,10 分至少要给我 5 分吧,另外一点好处是你先说出效率较低写法,再循序渐进给出优秀写法,可以给面试官你的罗辑思维能力,另外也会缩短算法考察的时长).
举个例子来讲,如果你的数据规模能够达到 ,那么很明显 的算法就不太适合本题了。
下面给出一个大概的数据规模和算法可接受的时间复杂度的对应表(记住,这里这是大致范围,算是经验之谈):
| 数据规模 | 算法时间复杂度 |
| — | — |
| <= 10
| O(n!)
|
| <= 25
| O(2^n)
|
| <=100
| O(n^4) |
| <= 500
| O(n^3)
|
| <= 2500
| O(n^2)
|
| <= 10^6
| O(nlogn) |
| <= 10^7
| O(n)
|
| <= 10^14
| O(sqrt(n))
|
| - | O(logn)
|
做题第二步:识别问题类型
我们在训练的初期,需要熟练各种解题模板。在熟练了解题的模板之后,我们才能够从题目内容倒退出题目的类型。
这也是为什么很多人推荐第一次要按照 tag 来进行刷题的原因,按照 tag 刷题也就意味着你可以对这种类型题目进行多方面强化,能够帮助你思考、总结、抽象到后面的举一反三。
按照 tag 刷题后,一般你会总结出常见的数据结构、思想以及算法,比如如下:
-
必须掌握的数据结构:数组、链表、栈、队列、堆、树、散列表、图、并查集
-
必须掌握的算法:递归、DFS 和 BFS、排序、二分法、双指针、滑动窗口
-
常用思想:分治、贪心、回溯、动态规划和分支界限
-
常见技巧:位运算、双指针、滑动窗口
在总结出这些常用抽象特征之后,往往你已经在 LeetCode 中已经过关斩将至少 100 题了。这也就意味着你已经进入了可以举一反三、联想关联的时候了。
但很多人在看到新题的时候还是不知道该如何联想到具体的解法,这通常意味着两点:
-
你对真正的解法理解的不够透,联想关联不够强
-
你对题目的抽象能力不够,也就是如何去除掉题目无关信息,提取出关键东西来
那么,这时候该怎么办。一个是在平时训练,尽量自己先想解法。如果实在想不出来(比如已经卡了一个小时了),就直接看答案,然后记录这道题目,过半个月在重新做一遍。
这里看答案也是有技巧的,你是怎么看答案的?你看答案的时候一定不能直接 copy 代码,而是先尽量理解答案的算法思路,然后用笔在纸上画出逻辑流程,如果不懂,再根据答案的示例代码脑袋里走一遍。最后关闭答案,自己写题目。
另外,我们可以通过题目关键字来帮助解题,我们在联想题解模板的时候,可以通过这些关键字来猜测。
- 如果题目中出现 连续子串, 连续子数组 这类的字眼,然后要求时间复杂度 ,那么你可以尝试用滑动窗口的思路解决。
举几个例子,比如 leetcode 中的 3. 无重复字符的最长子串
这道题目就是求最长的连续不含重复字符的子串,经典的滑动窗口题目。
76. 最小覆盖子串
同样可以抽取出来关键字 最小连续子串,而覆盖 T 中所有字符只是其中的制约条件而已,经典的滑动窗口题目。
解题第三步:草稿上写出算法思路
做算法题最忌讳的就是一看到题目,还没有想清楚思路和边界情况,就直接动手写代码。
能够直接动手写代码大概有几种情况:
-
你是超级大佬,比如楼教主这种
-
接近原题,或者这类题目你已经熟透了
-
题目太简单
但是,作为一般开发者,我还是推荐先写出算法思路。
举个例子,55. 跳跃游戏
我更加期望你能够这么在稿纸上写(当然你没有必要写这么多的字):
我们从开头开始遍历整个数组,并且维持一个最远距离值 max, 在遍历过程过,我们需要不断更新目前可以跳到最远的位置,也就是 max。
在遍历过程中,我们需要判断看当前位置是否小于等于 max:
- 如果是,继续下一个位置
- 如果大于 max,则表示无法到达最后一个位置
遍历结束可以在访问到最后一个元素或者通过判断 max 是否大于最后位置。
有了思路,我们写代码的时候往 bug free 就更进一步了
解题第四步:考虑边界情况
在有了思路之后,还需要提前考虑所有的边界情况以及初始情况。就拿上面的 55. 跳跃游戏 来讲,边界情况就是数组为空的时候:if(!nums.length) return true;
初始情况就是下标为 0 的时候:let max = nums[0] + 0;
最后代码就出来了:
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
if(!nums.length) return true;
let max = nums[0];
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。
技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取。
[外链图片转存中…(img-Jnv4vnMR-1713669649657)]
最后
技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。
技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取。
[外链图片转存中…(img-97sX7BTS-1713669649657)]