我们通常检验代码的方式采用单元测试的形式,经过实际的代码运行来判断代码有无问题。
这种方式也可以统计运行效率(打印执行时间差),被称为过后统计法,存在以下以下问题:
因此我们需要一种无需执行代码或具体测试的方式,能够粗略地估计算法的执行效率的方法。
评估一个方法(算法)的优劣,一般从以下维度:
公式:T(n) = O(f(n))
大O复杂度表示方法只是表示一种变化趋势。
当 n (基数)很大时,公式中的低阶、常量、系数三部分并不左右增加趋势,因此能够忽略。
时间复杂度的全称是渐进时间复杂度(time complexity),表示算法的执行时间与数据规模之间的增长关系。
大O复杂度表示方法是一种估算方式,因此在进行估算时无需对全部代码进行阅读。
有三种形式和方式用于参考:
关注循环执行次数最多的一段代码
总复杂度等于量级最大的那段代码的复杂度
嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
【】表示可能的执行次数
逐行代码列举。
// 假设每行代码执行时间 T
func cal(int n){
int sum = 0 // 1T
for i:=0;i<=n;i++ { // 1T + nT + nT
sum = sum + i; // nT
}
}
// 总执行时间 (3n+2)*T
// 大O表示:T(n) = O(3n+2)
// 忽略常量:T(n) = O(n)
前文提到,大O是一种估算,对于常量可以忽略。
func cal(int n){
int sum = 0;// 忽略
for i:=1;i<=n;i++ { // 关注循环次数
for j:=1;j<=n;j++ { // 外循环 * 内循环 = n^2
sum = sum + i*j // 忽略
}
}
}
// 大O表示:T(n) = O(n2)
多个循环取最大。
func cal(int n) {
int sum := 0
for i:=0; i < n; i++) {
sum += i // O(n)
}
for j:=1; j< n {
j = j * 3 // O(log-3-n) => O(logn)
}
for x:=1;x<=n;x++ {
for y:=1;y<=n;y++ {
sum = sum + x*y // O(n^2)
}
}
}
// 大O表示:T(n) = O(n2) 取最大量级
空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系。
空间复杂度的估算相比时间复杂度要简单,主需要关心申请内存的空间和次数。
因此,O(logn)、O(nlogn) 对数阶复杂度基本上用不到。
当前还没有观点发布,欢迎您留下足迹!