时间复杂度和空间复杂度
判断效率时,应只关注程序的高次介数,而常数和底次可以忽略。
时间复杂度
定义
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,对T(n)随n的变化情况进行分析,并确定数量级。
表示(大O计法): T(n)=O(f(n))
推导方法:
- 用常数1取代运行时间中的所有加法常数。
- 只保留最高阶部分
- 忽略最高价的系数
- 得到大O阶
总的思路就是找出运行次数的表达式(是一个多项式的形式),只取最高阶项,并舍去系数就可以得到答案!
例如: 3x^3 + 2x^3 + 2x^2 + 1 就只取 x^3 , 大O阶就是 O(n^3)
分类
-
常数阶 O(1)
-
线性阶 O(n)
-
平方阶 O(n^2) O(n^3)(立方阶)
特殊1:
int n=100 for(int i=0;i<n;i++) { for(int j=i; j<n;j++) { printf("hello world"); } }
总次数:n+(n-1)+(n-2)+…+1=(n+1)n/2=1/2n^2+1/2n
因此大O阶: O(n^2)
-
对数阶 O(logn)
例子:
int i=1; int n=100; while ( i < n ) { i=i*2; }
在上述程序中,每次i为上一个i*2,即2^x=n时推出程序。
因此程序的总次数:x=log(2)n
因此大O阶: O(logn)
-
nlong阶 O(nlogn)
2n+3nlog(2)n+14
-
指数阶 O(2^n)
2^n
总结
-
在编程时,因该最求时间复杂度最低。
-
经过对比,时间复杂的关系:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
空间复杂度
概念
算法1:给出一个年份,进过运算得出是否为闰年。程序只需要1KB
算法2:建立年份数据库,当输入一个年份,直接在数据库中查找,判断是否为闰年。程序可能需要100KB
可以看出,提高空间复杂度可以换取时间复杂度。
表达: S(n)=O(f(n)),
其中f(n)是关于存储空间的函数。
总结
在算法设计的时候,应充分考虑应用背景(硬件,时间等)来判断应该需要多大的空间复杂度和时间复杂度。