算法的复杂度
算法:
定义: 算法是用于解决一系列问题的步骤
public static int add(int a, int b){
return a + b;
}
public static int sum(int n){
int sum;
for(int i=0;i<n;i++){
sum += i;
}
return sun;
}
使用不同的算法,解决同一个问题,效率可能不一样
如何评判一个算法的好坏
概念:
- 时间复杂度: 估算指令执行的次数
- 空间复杂度: 估算算法所占用的存储空间
复杂度的表示方法:
大O表示法:一般用大O来描述算法复杂度,它表示的是算法n对应的复杂度
忽略常数、系数、低阶
-
9 >> O(1)
-
2n + 3 >> O(n)
-
n2 + 2n + 3 >> O(n2)
……
注意:大O表示法仅仅是一种粗略的分析模型,是一种估算,能够帮助我们在短时间内了解一个算法的执行效率 -
对数阶一般省略底数
- l o g 2 n {log_2{n}} log2n = l o g 9 n {log_9{n}} log9n * l o g 2 9 {log_2{9}} log29
所以 l o g 2 n {log_2{n}} log2n和 l o g 9 n {log_9{n}} log9n都称为 l o g n {log{n}} logn
常见的复杂度
执行次数 | 复杂度 | 非正式术语 |
---|---|---|
12 | O(1) | 常数阶 |
2n + 3 | O(n) | 线性阶 |
n2 + 2n | O(n2) | 平方阶 |
4 l o g 2 n {log_2{n}} log2n + 6 | O( l o g n {log{n}} logn) | 对数阶 |
n l o g 2 n {log_2{n}} log2n +34 | O(n l o g n {log{n}} logn) | n l o g n {log{n}} logn阶 |
2n3 + 3n2 + 2 | O(n3) | 立方阶 |
2n | O(2n) | 指数阶 |
- O(1) < O( l o g n {log{n}} logn) < O(n) < O(n l o g n {log{n}} logn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
例如:斐波那契数列
- 算法一
/**
* 斐波那契数列 0 1 1 2 3 5 8……
* 求第n个费波纳希数列的值
*/
private static int feb(int n) {
if (n <= 2) {
return n;
}
return feb(n - 1) + feb(n - 2);
}
- 算法2
/**
* 0 1 2 3 4 5 6 7
* 费斐波那契数列 0 1 1 2 3 5 8 13……
* 求第n个费波纳希数列的值
*/
private static int feb2(int n) {
if (n <= 1) return n;
int first = 0, second = 1, sum;
for (int i = 0; i < n - 1; i++) {
//n=4
sum = first + second; //first:0 second=1
first = second;
second = sum;
}
return second;
}
}
算法的优化方向
- 用尽量少的存储空间
- 用尽量少的执行步骤
注意: 适当的情况可以空间换时间 时间换空间