算法系列
主要记录一个前端学习算法的思考,核心语言是 JavaScript
圈内,对于算法,普遍都怀有敬畏之心,觉得算法是一个需要高智商,来学的东西。 原来我也对算法不肖一顾(搞不定,所以装作看不起),但在真正学习算法过程中,发现算法其实是有套路,有方法来搞的。多刷刷算法,会发现自己代码效率提升很多,而且更多自信,敢挑战更高更难的工作(最近,重构一些历史代码,但因对自己码力的自信,可以,也敢干它)
学习算法的目的
1.准备面试(大多数人)
面试中,现在一般都需要手写算法,为什么要考察算法 答:因为面试一两个小时,根本不可能全面了解面试者。所以,基于算法写的好的,代码能力不会太差(反之:代码好的人,不见得算法好;但和高考一样是一个人才的赛选机制)
那面试官主要考察那些能力呢?
- 分析问题能力
- 写代码能力(也就是传说中的码力)
具体考察的指标?
- 代码是否可运行
- 算法写的时间
- 代码运行效率
好一点的面试官,会在面试者写完算法后,进行探讨:
- 思路
- 时间负责度,空间复杂度
- 优化 (ps: 我经历的绝大多数面试,基本上,没有深究过。面试官可能都是从哪里搜的一道算法题,大概率的面试官自己都不会做)
综上:如果要面试搞定算法
- 熟悉主流算法套路(其实,绝大多数算法都可以暴力求解,然后优化套路也是相通的)
- 给自己倒计时,多次刷同一道题,刻意练习
- 优化 ,其实还是第一步的套路,熟悉常用(递归,回溯,贪心等)的套路,
2.让自己变更聪明
天天业务代码,写着多没意思;算法是浓缩编码的过程,可以让你达到 一年工作获得三年工作经验
如何学
1. 算法解题思路
2.算法基础——数据结构的遍历
参考 对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增删查改。 数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效地增删查改。话说这不就是数据结构的使命么? 如何遍历 + 访问?我们仍然从最高层来看,各种数据结构的遍历 + 访问无非两种形式:线性的和非线性的。 线性就是 for/while 迭代为代表,非线性就是递归为代表。再具体一步,无非以下几种框架:
数组遍历框架,典型的线性迭代结构:
functon traverse(arr=[]) {
for (int i = 0; i < arr.length; i++) {
// 迭代访问 arr[i]
}
}
链表遍历框架,兼具迭代和递归结构:
/* 基本的单链表节点 *
class ListNode {
int val;
ListNode next;
}
void traverse(ListNode head) {
for (ListNode p = head; p != null; p = p.next) {
// 迭代访问 p.val
}
}
void traverse(ListNode head) {
// 递归访问 head.val
traverse(head.next)
}
二叉树遍历框架,典型的非线性递归遍历结构:
/* 基本的二叉树节点 */
class TreeNode {
int val;
TreeNode left, right;
}
void traverse(TreeNode root) {
traverse(root.left)
traverse(root.right)
}
二叉树框架可以扩展为 N 叉树的遍历框架:
/* 基本的 N 叉树节点 */
class TreeNode {
int val;
TreeNode[] children;
}
void traverse(TreeNode root) {
for (TreeNode child : root.children)
traverse(child);
}