|
1 |
| -# leetcode-js |
2 |
| -前端数据结构和算法系统练习,冲击一线大厂 |
| 1 | +# 前端算法系统练习指南 |
| 2 | + |
| 3 | +## 适用人群 |
| 4 | +如果你正在为**面试**做准备,却对于庞杂的数据结构和算法知识,不知道何从下手; |
| 5 | + |
| 6 | +如果你以前曾经学过一些基础的数据结构或者算法的**基础知识**,却根本没有理解清楚,更不能独立完成算法的设计, 想重新巩固这方面的知识; |
| 7 | + |
| 8 | +如果已经有了一小段工作经验,但却老是在整天`用轮子`、`调API`当中度过,想看一看底层的源码却常常因**编程的内力**不足而放弃; |
| 9 | + |
| 10 | +如果你听说过`LeetCode`这个网站,想要一刷到底,迈向算法巅峰,却因为`浩瀚的题量`和`缺乏系统训练`感到无力,三天打鱼两天晒网,进而感到焦虑,甚至放弃...... |
| 11 | + |
| 12 | +如果上面任何一条符合你的现状,那么恭喜你,你来对了地方。作为一个圈内小有名气的[前端博主](https://juejin.im/user/5c45ddf06fb9a04a006f5491),我想借着我的影响力,分享出我系统梳理和练习的过程,希望能够帮助到更多跟我一样遇到类似困难的人,让你少一些不必要的折腾。 |
| 13 | + |
| 14 | +全程使用的语言是 `JavaScript`,因此标题上说的是前端xxx, 但实际上你也知道,数据结构和算法这东西主要是考验一个人的思维,至于语言,其中并没有用到任何 JS 的高深语法特性,只要有所编程经验,能理解代码是完全没有问题的,这一点大家放心。 |
| 15 | + |
| 16 | +## 算法没有用? |
| 17 | +我想各位当中肯定有准备面试的同学,那么你肯定听说过`面试造火箭,工作拧螺丝`, 不少人也拿这句话拿来诟病当前一些互联网大厂的算法面试,因此就有这样的言论: **除了应付面试,学算法其实没啥用**。 |
| 18 | + |
| 19 | +这句话我并不完全反对,因为现在随着技术生态的发展,各位走在领域前沿的大牛们已经给大家备足了轮子,遇到一般的业务问题直接把人家的方案拿到用就可以了,另外我也看到过一句话,刚开始觉得扯淡,后来想想觉得有那么一丝道理: |
| 20 | + |
| 21 | +> 凡是需要跨过一定智商门槛才能掌握的技术,都不会轻易的流行。 |
| 22 | +
|
| 23 | +换句话说:技术变得更简单,别人更愿意用,更容易流行。 |
| 24 | + |
| 25 | +这也是当前各种技术框架的真实写照: **足够好用,足够简单,简单到你不需要知道底层复杂的细节**。 |
| 26 | + |
| 27 | +那么问题来了,作为一个集智慧和才华于一身的程序员,自己的价值在哪里? |
| 28 | + |
| 29 | +我觉得价值的大小取决于你能够解决的问题,如果说照着设计稿画出一个简单的 Button,你能完成,别的前端也能完成,甚至后后端的同学都能把效果差不多做出来,那这个时候就谈何个人价值?只不过在一个随时**可替代**的岗位上完成了大多数人能轻易做到的事情,张三来完成,或者李四来完成,其实没什么区别。 |
| 30 | + |
| 31 | +但是现在如果面对的是一个复杂的工程问题,需要你来开发一个辅助业务的**脚手架工具**,改造**框架源码**来提高项目的扩展性,或者面对严重的性能问题能马上分析出原因,然后给出解决的思路并在不同因素中**平衡**,这些都不是一个业余的玩家能够在短时间内胜任的,这就是体现自己价值的地方。 |
| 32 | + |
| 33 | +回到算法本身,它代表的是你**解决更加复杂问题**能力的一部分。 |
| 34 | + |
| 35 | +可能干讲不容易理解,我们以 Vue 这个框架为例,如果你以前没有接触过`深度优先遍历`和`递归`的概念,没有看过相应的代码,那么虚拟 DOM 整个`patch`的源码你是基本不可能看懂的;如果你没有系统掌握过`栈`先进后出这种特点的应用,你也是很难理解 Vue 模板编译阶段为什么要用栈来检查标签是否正常闭合;同样的,如果你没有`回溯`这种算法的代码经验,你也是很难理解 Vue 模板编译的优化阶段,到底是怎样在**从父到子**深度优先遍历的过程中**检查到非静态的子节点**后给父节点打上标记;并且,如果你以前不知道 `LRU 缓存淘汰算法`究竟是个什么东西,你看到`keep-alive`组件的实现这里会非常纳闷: |
| 36 | +```js |
| 37 | +if (cache[key]) { |
| 38 | + vnode.componentInstance = cache[key].componentInstance |
| 39 | + // make current key freshest |
| 40 | + remove(keys, key) |
| 41 | + keys.push(key) |
| 42 | +} |
| 43 | +``` |
| 44 | +缓存命中了,为什么还要维护一个 keys 数组,而且把这个 key 从数组中删了,又要放到末尾,啥操作呢? |
| 45 | + |
| 46 | +如果之前有相应算法基础,你反而会觉得这个理所当然的事情。 |
| 47 | + |
| 48 | +看到了吧?你觉得尤大能写出优秀的“明星”项目,会没有一点扎实的数据结构和算法功底? |
| 49 | + |
| 50 | +当然不仅仅是前端领域,我想服务端也是差不多的情况,这里就不多举例了。 |
| 51 | + |
| 52 | +所以各位,我认为基本的算法能力对于一个想要解决复杂问题的工程师而言,不是一个加分项,而且是**必备项**。算法有大用。 |
| 53 | + |
| 54 | +## 如何系统练习? |
| 55 | + |
| 56 | +接下来我来分享一下练习数据结构和算法的一些心得,或者方法,分两个关键字来说: **系统**和**练习**。 |
| 57 | + |
| 58 | +### 专题突破 |
| 59 | +如何做到**系统**的训练? |
| 60 | + |
| 61 | +我想按照`LeetCode`上的顺序一题一题刷肯定不是系统,大部分情况是相邻的几个题毫无联系,这一题做了个链表相关的,下一题又是一个哈希表,再下一题又了一个二分搜索树,思维不断的跳转,一方面可能你的基础很薄弱,各个数据结构和算法理解的并不深刻,反复跳到你不熟悉的地方,会挫败你的信心,增加焦虑,甚至直接劝退,另一方面,可能再遇到难一点的`链表`题,你又不会了,可能你会纳闷: 不是刚刚才写出来了一个链表题吗?怎么现在又不会了?容易让你产生自我怀疑,也会影响你训练的自驱力。 |
| 62 | + |
| 63 | +因此我觉得分专题各个训练突破是一个相对合理的**战略**。在做到`专`和`精`的同时,也会让你掌握的更快,从而更容易解出类似的题,增强自信心。 |
| 64 | + |
| 65 | +另外要介绍的就是本系列的专题系统了,一共会分为这些模块: |
| 66 | +:::tip 专题目录 |
| 67 | +**链表篇**、**栈和队列篇**、**哈希表篇**、**二叉树篇**、**字典树**、**并查集**、**常见排序和查找算法**、**回溯算法**、**动态规划**、**贪心算法**、**LRU和LFU**、**字符串和正则篇** |
| 68 | +::: |
| 69 | +一共十二个模块,相信你会有不错的收获。 |
| 70 | + |
| 71 | +### 刻意练习 |
| 72 | +《**异类:不一样的成功启示录**》这本书里面谈到一万小时**刻意练习**成为高手的理论,后面也很多人谈到这个理论,我几年前就听说过,但真正体会到它的实际意义却是最近在训练算法的过程中,而且是走了很多弯路之后。可见理论到实际的过程是多么艰难。 |
| 73 | + |
| 74 | +我所理解的刻意练习,运用到算法的训练上面来,就是两点: |
| 75 | + |
| 76 | +1. 经常性地做你不会做的题 |
| 77 | + |
| 78 | +2. 多种解法方式轮流试,最大化地挖掘一道题的价值 |
| 79 | + |
| 80 | +**刻意练习**有一个重要的观点是`走出舒适圈`。对于算法练习也是一样,为什么很多人觉得刷算法没用,那是因为他们总是在做自己熟悉的题型,用自己熟悉的方法,蹲在自己的舒适圈,这样做的再多也意义不大,但是如果总是在做自己不熟练的题型,用不一样的方法,对于自己思维的成长是相当有帮助的,所以我觉得把握经常性地做不会的题,这样做的越多越好,当然了,时间有限,我们需要根据自己的需要来取舍。 |
| 81 | + |
| 82 | +之所以我会把这个系列叫做**练习**,而不是刷题,就是因为练习的本质是`练`,而不是简单的`AC`就可以。比如下面这一题: |
| 83 | + |
| 84 | +http://47.98.159.95/leetcode-js/example.jpg |
| 85 | + |
| 86 | +可能有经验的同学,用递归的方式很容易就解出来了。但是,你有想过如何用非递归的方式吗?如果能用非递归来是实现一遍,相信给自己带来的帮助和提升会比递归解大得多。 |
| 87 | + |
| 88 | +另外说一句,本系列中所有的代码都是原创的,而且不仅仅给出递归代码,在绝大多数情况下会给出对应的非递归解法,深入地挖掘一道题的最大价值,达到**练习**而不是刷题的效果。 |
| 89 | + |
| 90 | +最后的最后,我要强调的是: 对于这种修炼内功的练习,任何视频或者专栏都仅仅只是辅助作用,最重要的是还是自己的坚持和独立思考,如果你通过我这个系列能够让自己的算法能力更上一层楼,或者说能够有所收获,你应该感谢的是你自己。如果觉得这个系列还不错,希望能给这个项目点一个 star,非常感谢! |
0 commit comments