我正在参加「掘金·启航计划」
前端算法
有很多人觉得,前端中刷算法只是为了在面试的时候能脱颖而出,在实际工作中真正用到算法的场景非常少。这种想法也不是不无道理,很多业务场景下无论前端还是后端,徒手实现算法真的是少之又少。所以很多人会忽略算法,专精业务。但是据此得出算法不重要的结论还是太片面,为什么高阶面试中总会问到算法呢?因为算法很好地反映了面试者的编程思维和计算机知识素养。此外,如果我们想进阶,算法也是必须要攻克的一道难关。
既然要攻克算法,除了要先了解数据结构及其相关方法,重点还是要多看、多想、多刷,不仅仅是理解,动手写才是提高算法能力的关键。 。
本文会以以下几个方面逐一讲述:
-
算法复杂度
-
时间复杂度
-
空间复杂度
-
-
排序算法
-
动态规划
时间复杂度
算法复杂度是学习算法的基础。什么是复杂度,就是程序执行时需要的计算量和内存空间。而复杂度是一个数量级,并不是具体的数字。
先来看一下时间复杂度。一个算法的时间复杂度反映了程序运行从开始到结束所需要的时间。 时间复杂度算法中基本操作的重复执行次数(频度)即可看作算法的时间复杂度。
但是,时间复杂度的计算既可以有理可依,又可以靠主观感觉。通常来说,对时间复杂度的主观认知如下。
-
当代码中没有循环语句时,将时间复杂度记作 O(1),我们称之为常数阶。
-
当代码中只有一重循环时,算法基本操作的执行频度与问题规模n 呈线性正相关关系,记作O(n),我们称之为线性阶。
-
当代码中只有两重循环时,算法基本操作的执行频度与问题规模n 呈线性正相关关系,记作O(n^2)。
-
此外,还有O(logn) 、 O(nlogn)。
读者需要准确理解的是,由于时间复杂度描述的是算法执行时间与数据规模增长的变化趋势,所以常量、低阶、系数实际上对这种变化趋势不产生决定性影响,所以在做时间复杂度分析时可以忽略这些项。
空间复杂度
空间复杂度表示算法的存储空间与数据规模之间的增长关系。有的题目要求不额外增加空间,是指使用 O(1)空间在输入的空间上进行原地操作,如字符串反转。
对于时间复杂度和空间复杂度,开发者应该有所取舍,可以考虑牺牲空间复杂度降低时间复杂度,反之亦然。
排序算法
当我们了解了算法的 时间复杂度 和 空间复杂度之后,我们可以开始分析比较各个排序,首先常见的排序算法有以下几种:
冒泡排序
冒泡排序就是比较相邻的两个元素,把单独排序这两个元素(第一项比第二项大就交换位置,若为否则不动)第一次遍历数组的时候会确定整个数组最大的元素,那么第 N 次遍历就会确定 数组-N 的元素,当 N 等于数组长度的时候,就代表整个数组已经排序好了。
选择排序
选择排序的关键字是“最小值”:循环遍历数组,每次都找出当前范围内的最小值,把它放在当前范围的头部;然后缩小排序范围,继续重复以上操作,直至数组完全有序为止
插入排序
插入排序就像打扑克时整理手牌,抽出一张未排序的牌将它插在已经整理过的牌组中,通过扩大有序牌组,最终使得整副牌都有序
归并排序
归并排序将数组对半切割,直到每个子数组都只有一个元素,然后再将他们排序并且两两合并,直到整个数组仅有一个子数组。
归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。
快速排序
快速排序在基本思想上和归并排序是一致的,仍然坚持“分而治之”的原则不动摇。区别在于,快速排序并不会把真的数组分割开来再合并到一个新数组中去,而是直接在原有的数组内部进行排序。
以上gif,均来源于网络
两题简单的算法
对于经常刷算法的同学,看到这种题,应该会马上想到栈,解题思路是使用栈的数据结构,通过进栈和出栈,遍历一遍。
那么此时的时间复杂度为 O(n)。空间复杂度为O(n+∣Σ∣),其中 Σ 表示字符集。
瞄一眼这道题,与上面那题有点类似,但是这一道并不能用上题解法再解一遍。这道题正常解答有两种方式,
- 第一种是用指针,双指针的思路,一前一后向中间移动。此时的时间复杂度为 O(n)。空间复杂度为 O(1)。
- 第二种思路是直接翻转字符串再与原字符串判断是否相等实现。此时的时间复杂度为 O(n)。空间复杂度为 O(n)。
参考资料:
前端算法与数据结构面试:底层逻辑解读与大厂真题训练
zhuanlan.zhihu.com/p/449501682
leetcode.cn/problems/va…
leetcode.cn/problems/va…