1,冒泡排序;2,选择排序;3,桶排序;4,插入排序;5,归并排序;6,快速排序;7,时间复杂度与空间复杂度。

登录以参加训练计划

一般试题的时间限制是 1 秒。在这种情况下,C++ 代码中的操作次数控制在 10710^7 为最佳。

下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:

  • n30n \leq 30, 指数级别,
    • dfs + 剪枝,数字排列,n皇后问题,八数码问题
    • 状态压缩 dp,蒙德里安的梦想,最短 Hamilton 路径
  • n100n \leq 100 => O(n3)O(n^3)
    • floyd,
    • dp,
  • n1000n \leq 1000 => O(n2)O(n^2)O(n2logn)O(n^2\log{n})
    • dp,
    • 二分,
    • 朴素版 Dijkstra、朴素版 Prim、Bellman-Ford
  • n10000n \leq 10000 => O(nn)O(n\sqrt{n})
    • 块状链表、分块、莫队
  • n100000n \leq 100000 => O(nlogn)O(n\log{n}) 各种 sort,线段树、树状数组、set/map、heap、dijkstra+heap、prim+heap、spfa、求凸包、求半平面交、二分
  • n1000000n \leq 1000000 => O(n)O(n), 以及常数较小的 O(nlogn)O(n\log{n}) 算法
    • hash、双指针扫描、并查集,kmp、AC 自动机,
    • 常数比较小的 O(nlogn)O(n\log{n}) 的做法:sort、树状数组、heap、dijkstra、spfa
  • n10000000n \leq 10000000 => O(n)O(n)
    • 双指针扫描、kmp、AC 自动机、线性筛素数
  • n109n \leq 10^9 => O(n)O(\sqrt{n})
    • 判断质数
  • n1018n \leq 10^{18} => O(logn)O(\log{n})
    • 最大公约数,快速幂
  • n101000n \leq 10^{1000} => O((logn)2)O((\log{n})^2)
    • 高精度加减乘除
  • n10100000n \leq 10^{100000} => O(logn×loglogn)O(\log{n} \times \log{\log{n}})
    • 高精度加减、FFT/NTT

算法时间复杂度分析实例:

一般来说,k重循环,算法时间复杂度就是 nkn^k

基础算法

  • 快速排序 归并排序 二分 O(nlogn)O(n\log{n})
  • 双指针 数组元素目标和 O(n)O(n)

数据结构

  • 单链表 栈 (插入 删除操作) O(1)O(1)
  • 单调栈 单调队列 O(n)O(n)
  • KMP O(n)O(n)
  • Trie字符串统计 O(n)O(n)
  • 并查集 (路径压缩) O(nlogn)O(n\log{n})
  • 堆排序 O(nlogn)O(n\log{n})
  • 模拟散列表 O(1)O(1)

搜索与图论

  • 排列数字(全排列) O(nn!)O(n \cdot n!)
  • dfs bfs O(n+m)O(n+m)
  • Dijkstra O(mlogm)O(m\log{m})
  • Bellman_ford O(nm)O(nm)
  • spfa O(nm)O(nm)
  • Floyd O(n3)O(n^3)
  • Prim O(n2)O(n^2)
  • Kruskal O(mlogm)O(m\log{m})
  • 染色法判定二分图 O(mlogm)O(m\log{m})
  • 匈牙利算法 O(nm)O(nm)
  • spfa算法,匈牙利算法,最大流算法时间复杂度理论值很大,但是实际运行速度很快

数学知识

  • 试除法判定质数 分解质因数 n\sqrt{n}
  • 筛质数 nlognn\log{n}
  • 最大公约数 logn\log{n}
  • 快速幂 logn\log{n}

动态规划问题的计算量=状态数量*状态转移的计算量

动态规划

  • 背包问题 k重循环,算法时间复杂度就是 nkn^k
  • 最长上升子序列 II nlognn\log{n}
  • 蒙德里安的梦想 22nn2^{2n} \cdot n
  • 没有上司的舞会 nmnm

空间复杂度分析

  • 64M = 2262^{26} Byte
  • 2262^{26} Byte / 4 = 2242^{24} int = 1.6 * 10710^7 int

注意

  • 递归也是需要空间的,递归调用了系统栈,快速排序使用了递归,所以空间复杂度是 O(logn)O(\log{n})
  • C++ 中 bool 类型是 1 Byte (8 bits) 长,这是因为 C++ 的数据类型必须是可以通过地址访问的(addressable)。我们无法通过一位创建一个指针,但可以通过一个字节创建一个指针。因此,在 C++ 中,bool 类型的大小是一个字节。敬请期待

章节 1. 新手

开放

题目 尝试 AC 难度
P109  练19.2  三个数 53 18 1
P247  【例41.2】 绝对值排序 64 11 8
P412  【例71.1】 字典序排序 56 7 8
P488  选择排序 104 12 9

章节 2. 师傅

开放

题目 尝试 AC 难度
P1  【例2.1】Hello World 362 91 1

章节 3. 大神

开放

题目 尝试 AC 难度
P1  【例2.1】Hello World 362 91 1
 
参加人数
32
创建人