算法(一)——总述

482 阅读3分钟

算法系列

  1. 算法(一)——总述
  2. 算法(二)——动态规划

主要记录一个前端学习算法的思考,核心语言是 JavaScript

圈内,对于算法,普遍都怀有敬畏之心,觉得算法是一个需要高智商,来学的东西。 原来我也对算法不肖一顾(搞不定,所以装作看不起),但在真正学习算法过程中,发现算法其实是有套路,有方法来搞的。多刷刷算法,会发现自己代码效率提升很多,而且更多自信,敢挑战更高更难的工作(最近,重构一些历史代码,但因对自己码力的自信,可以,也敢干它)

学习算法的目的

1.准备面试(大多数人)

面试中,现在一般都需要手写算法,为什么要考察算法 答:因为面试一两个小时,根本不可能全面了解面试者。所以,基于算法写的好的,代码能力不会太差(反之:代码好的人,不见得算法好;但和高考一样是一个人才的赛选机制)

那面试官主要考察那些能力呢?

  1. 分析问题能力
  2. 写代码能力(也就是传说中的码力)

具体考察的指标?

  1. 代码是否可运行
  2. 算法写的时间
  3. 代码运行效率

好一点的面试官,会在面试者写完算法后,进行探讨:

  1. 思路
  2. 时间负责度,空间复杂度
  3. 优化 (ps: 我经历的绝大多数面试,基本上,没有深究过。面试官可能都是从哪里搜的一道算法题,大概率的面试官自己都不会做)

综上:如果要面试搞定算法

  1. 熟悉主流算法套路(其实,绝大多数算法都可以暴力求解,然后优化套路也是相通的)
  2. 给自己倒计时,多次刷同一道题,刻意练习
  3. 优化 ,其实还是第一步的套路,熟悉常用(递归,回溯,贪心等)的套路,

2.让自己变更聪明

天天业务代码,写着多没意思;算法是浓缩编码的过程,可以让你达到 一年工作获得三年工作经验

如何学

1. 算法解题思路

2.算法基础——数据结构的遍历

参考 对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增删查改。 数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效地增删查改。话说这不就是数据结构的使命么? 如何遍历 + 访问?我们仍然从最高层来看,各种数据结构的遍历 + 访问无非两种形式:线性的和非线性的。 线性就是 for/while 迭代为代表,非线性就是递归为代表。再具体一步,无非以下几种框架:

数组遍历框架,典型的线性迭代结构:

![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e4780898e3c84c8d8c082ce9cbc11c50~tplv-k3u1fbpfcp-zoom-1.image)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);
}