Skip to content
Algorithms to Remember

Algorithms to Remember

递归主定理

T(n)=aT(n/b)+f(n)T(n) = a T(n/b) + f(n), c=logbac = \log_b a

  • f(n)=O(ncϵ)f(n) = O(n^{c-\epsilon}): T(n)=Θ(nc)T(n) = \Theta(n^c)
  • f(n)=Θ(nclogkn)f(n) = \Theta(n^{c}\log^k n): T(n)=Θ(nclogk+1n)T(n) = \Theta(n^c \log^{k+1}n)
  • f(n)=Ω(nc+ϵ)f(n) = \Omega(n^{c+\epsilon}), af(n/b)kf(n)af(n/b)\le kf(n) (正则条件): T(n)=Θ(f(n))T(n) = \Theta(f(n))

AVL 树(平衡二叉搜索树)

  • 旋转:左旋/先右旋后左旋/右旋/先左旋后右旋(根据失衡节点与子节点的平衡因子决定)
  • 插入、删除:自底向上解决失衡节点

红黑树

WIP

图的遍历

DFS 和 BFS 均有 O(m+n)O(m+n) 时间复杂度和 O(n)O(n) 空间复杂度

搜索算法

  • 暴力搜索:线性搜索、BFS、DFS
  • 自适应搜索:二分查找、哈希表、二叉搜索树、AVL 树

排序算法

计数排序:计算计数数组的前缀和,从后往前填充

图论算法

  • 并查集:第一次查询操作O(logn)O(\log n)(包括findjoin),后续趋近于O(1)O(1)
  • DFS、BFS:O(n+m)O(n+m)(使用栈/队列实现,注意标记和检测visited数组的时间)
  • 最小生成树:Prim O(n2)O(n^2)(距离数组实现)/O(mlogm)O(m\log m)(优先队列实现)(这个关系与Dijkstra算法一致),Kruskal O(mlogm)O(m\log m)(优先队列、并查集实现)
  • 拓扑排序:O(n+m)O(n+m)(本质上与BFS相同)
  • 通用搜索算法总结:O(n+m)O(n+m)(栈/队列)、O(mlogm)O(m\log m)(优先队列,如果可以修正队列元素则为O((n+m)logn)O((n+m)\log n))、O(n2)O(n^2)(距离数组)
    • DFS、BFS:使用栈与队列,指定起点(优先级/距离均为1)
    • 拓扑排序:使用队列,起点为入度为0的节点(优先级/距离均为1)
    • Dijkstra:使用节点到起点的距离作为距离数组元素/边的优先级
    • Prim:使用节点到生成树到距离作为距离数组元素/边的优先级
  • 最短路径:
    • Dijkstra:单源、权值非负,O(n2)O(n^2)(稠密图)/O(mlogm)O(m\log m)(稀疏图)
      • A*可用于权值修正,更快找到首个有效解
      • 要添加边数限制,则不适用于Dijkstra,只能采用二维距离数组(动态规划思想,同时考虑不同边数的路径),O(km)O(km)
    • Bellman-Ford:单源、负权边、检测负权回路,O(mn)O(mn)(可使用队列优化稀疏图平均情况、最优情况的时间复杂度)
    • Floyd-Warshall:多源、负权边、检测负权回路(算法结束后检测dist[i][i]),O(n3)O(n^3)(矩阵可压缩为二维)