算法知识学习图谱,内容按照下面👇图片设计

工具

  • Google 搜索引擎
  • iTerm2 + zsh 最强终端体验
  • heyfocus.com
  • IDEA+LeetCode plugin
  • LeetCode

复杂度

时间复杂度

计算机科学中,算法时间复杂度(Time complexity)是一个函数,它定性描述该算法的运行时间。

这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。

为了计算时间复杂度,我们通常会估计算法的操作单元数量,每个单元运行的时间都是相同的。因此,总运行时间和算法的操作单元数量最多相差一个常量系数。

时间复杂度分为:

  • O(1) 常数复杂度,最佳,比如Hash表,缓存等
  • O(log n)仅次于常数复杂度,如 二分查找、二叉搜索树等
  • O(n) 线性复杂度,如大多数遍历操作
  • O(n^2)双重for循环
  • O(2^n)递归的时间复杂度

空间复杂度

算法的空间复杂度是指算法需要消耗的空间资源。其计算和表示方法与时间复杂度类似,一般都用复杂度的渐近性来表示。

空间复杂度分为:

  • O(1)原地操作
  • O(n)开辟线性辅助空间

数组

在计算机科学中,数组数据结构(英语:array data structure),简称数组(英语:Array),是由相同类型的元素(element)的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引(index)可以计算出该元素对应的存储地址。

特点:

  • 连续空间
  • 查找快,插入/删除节点慢

链表

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

特点:

  • 离散空间
  • 查找慢,插入/删除节点快

堆栈(英语:stack)又称为堆叠,是计算机科学中的一种抽象数据类型,只允许在有序的线性数据集合的一端(称为堆栈顶端,英语:top)进行加入数据(英语:push)和移除数据(英语:pop)的运算。因而按照后进先出(LIFO, Last In First Out)的原理运作。

堆栈常用一维数组链表来实现。

特点:

  • 先进后出

队列

队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。

特点:

  • 先进先出

映射

key和value一一对应关系,且key没有重复的.

集合

没有重复key

并查集

计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。

特性:

  • 站队问题
  • 初始化
  • 查询合并
  • 路径压缩

LRU

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

注意事项:

  • HashTable+双向链表
  • get 和 set 都收 O(1)的复杂度

布隆过滤器

布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间越来越大。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为{\displaystyle O(n),O(\log n),O(1)}

布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。

注意事项:

  • 判断不存在100%准确
  • 判断存在有误差
  • 利用Hash函数将判断Key对应到多个位上

位运算

位操作程序设计中对位模式二进制数的一元和二元操作。在许多古老的微处理器上,位运算比加减运算略快,通常位运算比乘除法运算要快很多。在现代架构中,情况并非如此:位运算的运算速度通常与加法运算相同(仍然快于乘法运算)。

注意事项:

  • 需要记忆一些常见的位运算公式

动态规划

动态规划(英语:Dynamic programming,简称DP)是一种在数学管理科学计算机科学经济学生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

注意事项:

  • 简单版本的递归加缓存
  • 高级版本是递归公式
  • 状态的定义
    • 有些场景需要套用模版
  • 最优子结构
  • 状态转移方程

贪心算法

贪心算法(英语:greedy algorithm),又称贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法

注意事项:

  • 判断能不能贪心
  • 弱化版的动态规划

二分查找

计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)[1]对数搜索算法(英语:logarithmic search algorithm)[2],是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

注意事项:

  • 有序
  • 有界
  • 能够通过索引随机访问

递归、分治

注意事项:

  • 盗梦空间 ?
  • 终止状态 ?
  • 本层处理 ?
  • Drill Down ?
  • 本层状态清理 ?

递归

递归的基本思想是某个函数直接或者间接地调用自身,这样就把原问题的求解转换为许多性质相同但是规模更小的子问题。

分治

归并排序 ,典型的分治算法;分治,典型的递归结构。

分治算法可以分三步走:分解 -> 解决 -> 合并

  1. 分解原问题为结构相同的子问题。
  2. 分解到某个容易求解的边界之后,进行递归求解。
  3. 将子问题的解合并成原问题的解。

一张图由一些小圆点(称为顶点结点)和连结这些圆点的直线或曲线(称为)组成。

注意事项:

  • 遍历时需要记录已经访问过的节点

在计算机科学中,(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

它具有以下的特点:

  • 每个节点都只有有限个子节点或无子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树;
  • 树里面没有环路(cycle)

二叉树

每个节点最多含有两个子树的树称为二叉树;

遍历方式

DFS 深度优先搜索算法

是一种用于遍历或搜索算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

BFS 广度优先搜索算法

BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。广度优先搜索的实现一般采用open-closed表。

二叉搜索树

一棵空树或者具有下列性质的二叉树

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。

平衡二叉树

平衡二叉搜索树(英语:Balanced Binary Tree)是一种结构平衡的二叉搜索树,它是一种每个节点的左右两子高度差都不超过一的二元树。它能在O(\log n)内完成插入、查找和删除操作

剪枝

删除不需要的二叉树节点操作

字典树

计算机科学中,trie,又称前缀树字典树,是一种有序,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。