时间复杂度
原因:使用时间复杂度分析是为了在不运行代码的情况下,粗略地估计一段代码的执行时间。
普通的执行测试结果受限于测试环境以及数据规模,因此需要一个不用具体的测试数据测试,便可以粗略地估计算法的执行效率的方法。
int cal(int n) {
int sum = 0;
int i = 1;
int j = 1;
for (; i <= n; ++i) {
j = 1;
for (; j <= n; ++j) {
sum = sum + i * j;
}
}
}
以上代码,假设执行代码的时间为1ut,则第2,3,4行各需要执行一次,记为3ut,第5,6行则需要各执行n遍,记为2nut,一次类推第7,8行为2n^2遍。所以最后所有加起来时间为(2n^2+2n+3)ut,用T(n)表示总时间,则T(n)=(2n^2+2n+3)ut。
虽然不知道ut单位的具体值,但可以看出T(n)与代码执行次数成正比。
用大O表示法为: T(n)=O(f(n))
f(n)表示每行代码执行次数的总和,公式中的O表示代码执行时间T(n)和f(n)之间的正比关系。
以上为大O时间复杂度表示法,它并不具体的表示真正的执行时间,表示的是代码执行时间随数据规模增长的变化趋势,因此也叫做渐进时间复杂度(asymptotic time complexity),简称时间复杂度。
时间复杂度分析方法
1、只关注循环执行次数最多的一段代码;
2、加法法则:总复杂度等于量级最大的那段代码的复杂度;
3、乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积。
常见时间复杂度:
复杂度量级(按照数量级递增): 常量阶 O(1)、对数阶 O(logn)、线性阶 O(n)、线性对数阶 O(nlogn)、平方阶 O(n^2)、立方阶 O(n^3)...k次方阶 O(n^k)、指数阶 O(2^n)、阶乘阶 O(n!)
对于以上可粗略地分为两类:多项式量级和非多项式量级。非多项式量级只有两个:指数阶O(2^n)和阶乘阶O(n!)。
时间复杂度为非多项式量级的算法问题叫做NP(Non-Deterministic Polynomial,非确定多项式)问题。
1、O(1)
执行一次的代码没有作为变化的n为循环条件的循环的程序,其时间复杂度为O(1);
2、O(logn)、O(nlogn)
示例:
int i = 1;
while(i<=n){
i = i * 2;
}
该方法的时间复杂度,实质为2^0 * 2^1 * 2^2 * ... * 2^x = n,
因此只需要知道x值就知道代码执行次数,前边(2^0 * 2^1 * 2^2 * ... )视为系数,则2^x=n, 导出x=log2n,以2为底,所以这段代码的时间复杂度是O(log2n)。
当将代码中2换成3则变成O(log3n),在数学中,log3n 就等于 log32 * log2n,所以 O(log3n) = O(C * log2n),其中 C=log32 是一个常量。而在采用大O标记复杂度时可忽略系数,即O(Cf(n))=O(f(n)),因此O(log2n)=O(log3n)。
同理无论log的底为多少都可以转换为O(logn)。
而O(nlogn)则很好理解了,用乘法法则,如果一段代码复杂度为O(logn),则执行n次的复杂度为O(nlogn)。
3、O(m+n)、O(m*n)
当代码中有两个变化趋势(复杂度由两个数据规模来决定),如果互不相关,则O(m+n);如果相互嵌套,则遵从乘法法则,O(m*n)
时间复杂度分析类型:最好情况时间复杂度(best case time compleyxity)、最坏情况时间复杂度(worst case time compleyxity)、平均情况时间复杂度(average case time compleyxity)、均摊时间复杂度(amortized time compleyxity)。
最好情况时间复杂度:在最理想情况下,执行这段代码的时间复杂度。(例如:执行第一次就得出结果完成执行)
最坏情况时间复杂度:在最糟糕情况下,执行这段代码的时间复杂度。(例如:执行完所有循环次数)
平均情况时间复杂度:要查找的变量x在数组的位置,由n+1种情况:在数组的0~n-1位置中和不在数组中。我们把每种情况下,查找需要遍历的元素个数累加起来,然后处以n+1,得到需要遍历元素个数的平均值。
公式
此处不是太明白。(1到n是遍历完得到x,最后的n表示遍历完n遍不在数组中,然后在进行等差数列推导)
加权求平均值方法,
也叫期望值,所以平均时间复杂度的全称应该叫做加权平均值时间复杂度或者期望时间复杂度。
均摊时间复杂度:每一次O(n)的插入操作,都会跟着n-1次O(1)的插入操作,所以把耗时多的那次操作均摊到接下来的n-1次耗时少的操作上,均摊下来,这一组连续操作的均摊时间复杂度就是O(1)。(摊还分析法)
=============================
平均与均摊分析
平均时间复杂度:
1)代码在不同情况下复杂度出现量级差别,则用代码所有可能情况下执行次数的加权平均值表示。
均摊时间复杂度在两个条件满足时使用:
1)代码在绝大多数情况下时低级别复杂度,只有极少数情况时高级别复杂度;
2)低级别与高级别复杂度出现具有时序性规律,均摊结果一般都等于低级别复杂度。