复杂度描述的是算法执行时间(或占用空间)与数据规模的增长关系。
大O时间复杂度表示法,表示代码执行时间(或占用空间)随数据规模增长的变化趋势。
时间复杂度
代码执行时间与每行代码执行次数成正比,T(n)=O(f(n)),T(n)表示代码执行的时间,n表示数据规模大小,f(n)表示每行代码执行次数总和,大O表示代码执行时间随数据规模增长的变化趋势。
例如:T(n)=O(2n+1)或者T(n)=O(2n2+2n+3),公式中低阶、常量、系数三部分并不会左右增长趋势,可以忽略,所以大O表示法只要取f(n)中最大量级的即可T(n)=O(n),T(n)=O((n2))
时间复杂度分析法则
1)单段代码看高频:比如循环。
2)多段代码取最大:比如一段代码中有单循环和多重循环,那么取多重循环的复杂度。
3)嵌套代码求乘积:比如递归、多重循环等
4)多个数据规模求加法:比如方法有两个参数控制两个循环的次数,那么这时就取二者复杂度相加。
常用复杂度量级(按量级递增)
多项式量级
- 常量阶 O(1)
- 对数阶 O(logn)
- 线性阶 O(n)
- 线性对数阶 O(nlogn)
- 平方阶 O(n2)、立方阶 O(n3)…k次方阶 O(nk)
非多项式量级
- 指数阶 O(2n)
- 阶乘阶 O(n!)
时间复杂度为非多项式量级的算法问题叫作 NP(Non-Deterministic Polynomial,非确定多项式)问题。
当数据规模 n 越来越大时,非多项式量级算法的执行时间会急剧增加,求解问题的执行时间会无限增长。所以,非多项式时间复杂度的算法其实是非常低效的算法。
空间复杂度
类比渐进时间复杂度, 空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系。
最好、最坏、平均情况时间复杂度
- 同一段代码,如果再不同情况下其时间复杂度出现了量级的差别,这时候就需要区分情况做时间复杂度分析。
- 最好情况时间复杂度、最坏情况时间复杂度:顾名思义;
- 平均情况时间复杂度:以数组查找某一值位置为例,引入概率,每种情况下查找的元素个数乘上概率1 × \times × 1 2 n 1 \over 2n 2n1 +2 × \times × 1 2 n 1 \over 2n 2n1+3 × \times × 1 2 n 1 \over 2n 2n1+…+n × \times × 1 2 n 1 \over 2n 2n1 + n × \times × 1 2 1 \over 2 21 = 3 n + 1 4 3n+1 \over 4 43n+1 即O(n),也就是加权平均值(期望值),所以平均情况时间复杂度也叫加权平均时间复杂度或者期望时间复杂度。【了解就好】
均摊时间复杂度
- 当一段代码,大部分操作都是较低的时间复杂度,少数的操作时间复杂度较高,并且这些操作出现的顺序有先后关联且规律。
- 这是后就可以用摊还分析法,试着将较高时间复杂度均摊到较低复杂度的操作上,得出的时间复杂度叫均摊时间复杂度。
- 一般均摊时间复杂度等于最好情况时间复杂度。
- 均摊时间复杂度是一种特殊的平均时间复杂度。
熄灯
最好、最坏、平均情况时间复杂度以及均摊时间复杂度了解就好,只有不通情况复杂度出现量级的差异才会考虑。一般按照基本是时间复杂分析方法就足够了,最好、最坏情况下的时间复杂度分析起来比较简单,但平均、均摊两个复杂度分析相对比较复杂。经常对代码进行简单的复杂度分析按感觉来,主要是用一定的分析方法,找出代码按数据规模变化执行时间的变化趋势。