Skip to content

Commit fb60e28

Browse files
authoredJan 27, 2020
Update README.md
1 parent 2fa0fe9 commit fb60e28

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed
 

‎README.md

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,90 @@
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

Comments
 (0)
Please sign in to comment.