写给前端的算法进阶指南
前言
最近国内大厂面试中,出现 LeetCode
真题考察的频率越来越高了。我也观察到有越来越多的前端同学开始关注算法这个话题。
但是算法是一个门槛很高的东西,在一个算法新手的眼里,它的智商门槛要求很高。事实上是这个样子的吗?看完这篇文章你就不会觉得了。
一定要耐心看到底,会有重磅干货分享给你。
送分题不能丢
你常常有听到说面试前刷 leetcode 的说法。但是在刷 leetcode 题目之前,我认为有些基础分必须拿到,或者说送分题必须不能丢。
什么是送分题?就是你大学数据结构或者是C语言教材遇到的那些题目。这些题目你做过,花一个学期学习过,即使现在忘了捡起来也算是容易的。例如数据结构里的那些排序算法,查找算法,还有树的相关知识。面试的题目相对于书的内容其实更窄,比如关于树的知识点,面试官的题目可能会暗示你是用二叉树去解决一个问题,或者计算叶子节点个数,或者计算树的深度。其他更简单的例如使用递归和非递归的方式写出二叉树的前中后序遍历。并不会考到例如平衡二叉树或者是完全二叉树的这样的概念(至少我没有遇到过),更不要说图这样的概念了。
查找算法遇见的不多,更多的是考察排序算法。算法的基本款是必须要掌握的:冒泡排序、选择排序、插入排序、快速排序、归并排序、桶排序。学会写这些算法是下策,上策是你要知道这些算法的原理和效率(也就是时间复杂度)。比如当你在面试里卡壳的时候,你至少可以描述算法是如何工作的。而之所以要了解它们的效率,是因为面试官有可能让你间接的写一个算法,例如不考虑空间效率,写一个时间效率最高的。学会判断时间复杂度很重要,在后面我们也会用到。
当你确保这些基础题都已经万无一失了。那么就可以开始尝试练习更难的题目了(抱歉我也不知道什么样才算更难得题目)。
当然难和容易依然是相对的,或许这些题目对我来说还算是简单,但是一部分人来说仍然困难。但无论如何都有你擅长和曾经遇到过的问题,稳扎稳打,这些送分题不能丢。
学习方式
1.分类刷题
很多第一次接触力扣的同学对于刷题的方法不太了解,有的人跟着题号刷,有的人跟着每日一题刷,但是这种漫无目的的刷题方式一般都会在中途某一天放弃,或者刷了很久但是却发现没什么沉淀。这里不啰嗦,直接点明一个所有大佬都推荐的刷题方法:把自己的学习阶段分散成几个时间段去刷不同分类的题型,比如第一周专门解链表相关题型,第二周专门解二叉树相关题型。这样你的知识会形成一个体系,通过一段时间的刻意练习把这个题型相关的知识点强化到你的脑海中,不容易遗忘。
2.适当放弃
很多同学遇到一个难题,非得埋头钻研,干他 2 个小时。最后挫败感十足,久而久之可能就放弃了算法之路。要知道算法是个沉淀了几十年的领域,题解里的某个算法可能是某些教授研究很多年的心血,你想靠自己一个新手去想出来同等优秀的解法,岂不是想太多了。所以要学会适当放弃,一般来说,比较有目的性(面试)刷题的同学,他面对一道新的题目毫无头绪的话,会在 10 分钟之内直接放弃去看题解,然后记录下来,反复复习,直到这个解法成为自己的知识为止。这是效率最高的学习办法。
3.接受自己是新手
没错,说的难听一点,接受自己不是天才这个现实。你在刷题的过程中会遇到很多困扰你的时候,比如相同的题型已经看过例题,稍微变了条件就解不出来。或者对于一个 easy 难度的题毫无头绪。或者甚至看不懂别人的题解(没错我经常)相信我,这很正常,不能说明你不适合学习算法,只能说明算法确实是一个博大精深的领域,把自己在其他领域的沉淀抛开来,接受自己是新手这个事实,多看题解,多请教别人。
如果你现在缺少学习资料,不知从何处下手,我正好从朋友那薅到一份《2021最新版数据结构与算法⾯试题⼿册》,硬着头皮全部啃完了,不直接看答案,先自己思考,不然很容易忘记,实在不会的看题解,看看别人的解题方法。做完了之后总结思路和常见套路。
1.哈希
- 请说⼀说,Java中的HashMap的⼯作原理是什么?
- 介绍⼀下,什么是Hashmap?
- 讲⼀讲,如何构造⼀致性哈希算法。
- 请谈⼀谈,hashCode() 和equals() ⽅法的重要性体现在什么地⽅?
2.⼆叉树
- 求⼆叉树的最⼤深度
- 求⼆叉树的最⼩深度
- 求⼆叉树中节点的个数
- 求⼆叉树中叶⼦节点的个数
- 求⼆叉树中第k层节点的个数
- 判断⼆叉树是否是平衡⼆叉树
- 判断⼆叉树是否是完全⼆叉树
- 两个⼆叉树是否完全相同
- 翻转⼆叉树or镜像⼆叉树
- 两个⼆叉树是否互为镜像
- 求两个⼆叉树的最低公共祖先节点
3.链表
- 谈⼀谈,bucket如果⽤链表存储,它的缺点是什么?
- 有⼀个链表,奇数位升序偶数位降序,如何将链表变成升序?
- 如何反转单链表
- 现在有⼀个单向链表,谈⼀谈,如何判断链表中是否出现了环
- 随机链表的复制
4.数组
- 写⼀个算法,可以将⼀个⼆维数组顺时针旋转90度。
- ⼀个数组,除⼀个元素外其它都是两两相等,求那个元素?
- 找出数组中和为S的⼀对组合,找出⼀组就⾏
- 求⼀个数组中连续⼦向量的最⼤和
- 寻找⼀数组中前K个最⼤的数
5.排序
- ⽤Java写⼀个冒泡排序?
- 介绍⼀下,排序都有哪⼏种⽅法?请列举出来
- 介绍⼀下,归并排序的原理是什么?
- 介绍⼀下,堆排序的原理是什么?
- 谈⼀谈,如何得到⼀个数据流中的中位数
- 你知道哪些排序算法,这些算法的时间复杂度分别是多少,解释⼀下快排?
6.堆与栈
- 请你解释⼀下,内存中的栈(stack)、堆(heap) 和静态区(static area) 的⽤法。
- 说⼀说,heap和stack有什么区别。
- 最⼩的k个数
- 滑动窗⼝最⼤值
- 丑数前
- 前K个⾼频元素
- 有效的括号
- 最⼩栈
- 柱状图中最⼤的矩形
7.⾼级算法
- 请你讲讲LRU算法的实现原理?
- 为什么要设计 后缀表达式,有什么好处?
- 请你设计⼀个算法,⽤来压缩⼀段URL?
- 谈⼀谈,id全局唯⼀且⾃增,如何实现?
- 最后⼀个单词的⻓度
8.动态规划
- 斐波那契数
- 不同路径
- 爬楼梯
- 零钱兑换
- 打家劫舍
- 编辑距离
想学习前端web和需要PDF文档的朋友都可以加入这边的企鹅裙,前面:938,,中间:051,,最后:673,
裙里从学生到大佬都有,资源免费分享,不见不散哦!