《啊哈算法》学习笔记

来源:互联网 发布:js slice 编辑:程序博客网 时间:2024/06/05 05:05

  • 时间复杂度
  • 排序
  • 队列栈链表
    • 队列
    • 链表
      • 模拟链表
  • 枚举穷举
  • 搜索
    • 深度优先搜索DFSDepth First Search
    • 广度优先搜索BFSBreadth First Search
    • 图的邻接矩阵存储法
    • Floyd-Warshall
      • 多源最短路径的套路模型
    • 负权回路负权环
    • Dijkstra
    • Bellman-Ford
    • 二叉树
    • 满二叉树
    • 完全二叉树

时间复杂度

时间复杂度计算的时候可以忽略较小的常数:如O(2*(M+N))中可以忽略2
可以忽略低阶:如O(N+N²)可以忽略N

排序

  1. 桶排序:对[0,n]方位的元素排序,就要使用n+1个桶,每个元素出现一次,就把对应的数组[n]+1,最后根据整个桶(即数组)进行输出或将元素放到其它数组即可,这个操作还可以增加一些功能,如去重、忽略一些元素等等
    ==占用内存大,但是可以比较容易地实现去重功能==
  2. 冒泡排序
  3. 快速排序:速度快,二分思想、递归;详见我的个人博客
  4. 去重的一种实现:利用中间代理模式,先排序,再读取后输出、放到目标数组,读取的时候发现重复的可以忽略不读
  5. 插入排序、基数排序计数排序、归并排序、堆排序
  6. ==注意:实际上桶排序比快速排序要快==

队列、栈、链表

队列

实现回文检测的时候,将回文的mid=len/2-1入栈,然后循环弹栈与剩下的mid+1(即len/2)对比即可
栈还可以用来验证括号匹配

链表

模拟链表

==使用两个数组来模拟链表:其中一个数组存储链表中的节点的数据,另一个或两个数组存储节点的上一个/下一个元素。==
模拟链表节点的增删:添加数据到数组并修改索引数组即可

枚举/穷举

snip

搜索

解决当下应该怎么做,‘下一步怎么做’与当下怎么做是一样的

void dfs(){    //1、判断边界    //2、尝试每一种可能    for(i = 1;i < len;++i)    {        //3、 继续下一步        dfs();    }    //4、返回    return ;}

==又称为宽度优先搜索==
每个点的每个方向尝试一次搜索,不像DFS那样每个方向递归尝试搜索直到不能再递归为止。

==涉及图的问题的时候,注意图会不会存在负权==

图就是M个边和N个顶点组成的集合

图的邻接矩阵存储法

==用二维数组的[i][j]来表示顶点i到顶点j是否有边连通,用1表示有边,用∞表示没有边(应该可以自己决定),用0表示自己到自己(即i == j的情况)==

图包括有向图和无向图

==把图转换为二维数组后再用DFS间接求得连通性==

==对图进行DFS或BFS都能够得到这个图的生成树==

==对图来说一个重要的思想:如果想让两个顶点之间的路程减小,那么一般需要引入第三个甚至多个顶点作为中转==

==图的每个顶点都可能使另外两个顶点之间的距离减小==

Floyd-Warshall

==Floyd-Warshall算法:核心部分5行解决图的最短路径问题(动态规划思想);时间复杂度:O(N³)(因为是N个元素–>Range为N的三重嵌套循环)==

Floyd-Warshall用于求多源最短路径:即图中两个点之间的最短路径

多源最短路径的套路模型

负权回路(负权环)

图中的多个顶点和多条边组成的闭合环,这个环走完一圈后会使距离减少,每次走这个环都会使距离越来越小:因为这个环内有边是负的,且负的总值大于正的,所以路程越走越少,即为负权

==如果一个图中带有负权回路,则这个图没有最短路径==

Dijkstra

Dijkstra用于求单源最短路径:求一个顶点到其余各顶点的最短路径

Bellman-Ford

对每条边做n-1次松弛,可以解决负权边

树就是不包含闭合回路的连通无向图

树是任意两个节点之间有且只有一条路径的无向图

注意:==同一种树在视觉上可以有若干种表示方式(主要原因是根节点可以有多种选择)==

==只要出现闭合回路,那就是图,否则就是树==

====特别注意:如果一棵树有N个节点,那么它必然有N-1个边/树枝====,在树中加一条边,会构成一个闭合回路

树的节点分为==根节点、叶子节点、内部节点==

二叉树

一个二叉树的每个节点最多只能有两个子节点(==0和1个子节点也属于二叉树==)

一棵多叉树可以转换为二叉树

满二叉树

所有==内部==节点都有两个子节点;有h层时,拥有节点2^h-1个节点

完全二叉树

除最后一层从右往左有连续的几个节点没有两个子节点,其他子节点全满