时间复杂度
1.时间复杂度判断 一般法则
1.1----for循环
for循环的运行时间至多是for循环内部代码的运行时间乘for循环的迭代次数
public static int sum(int n){
int partOne;
partOne = 0;
for (int i=1 ;i<n;i++){
partOne += i*i*i;
}
return partOne;
}
上例代码for循环的运行 n*1次所以时间复杂度为 O(n)
1.2---嵌套for循环法则
分析嵌套循环的诀窍是 从里向外分析这些循环:
言语不足以表达,且看画图大法:
for (int i=1 ;i<n;i++){-----------------------------n
for(int j=1;j<n;j++){ -------------------n
for(int x=1 x<3 ;x++){---------- 3
partOne += i*i*i;
}
}
}
所以时间复杂度计算应该为 3*n*n=3n^2 O(n^2)
1.3----顺序语句
对于顺序语句在计算时间复杂度时,总的时间复杂度等于最大的时间复杂度
void aFunc(int n) {
---------------------------------------------------------
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
printf("Hello, World!\n"); ---------时间复杂度为O(n^2)
}
}
---------------------------------------------------------
for(int j = 0; j < n; j++) {
printf("Hello, World!\n"); ---------时间复杂度为O(n)
}
---------------------------------------------------------
}
上例中总的时间复杂度为 max(O(n^2),O(n)) = O(n^2)
1.4----if else
对于条件判断的语句计算时间复杂度,那条路径的时间复杂度最大,那么这条路径的时间复杂度就是条件语句的时间复杂度。
void aFunc(int n) {
if (n >= 0) {
---------------------------------------------------------第一条路径----------
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
printf("输入数据大于等于零\n"); >>>>>>>>>>>>>>时间复杂度O(n^2)
}
}
-----------------------------------------------------------------------------
} else {
---------------------------------------------------------第二条路经----------
for(int j = 0; j < n; j++) {
printf("输入数据小于零\n"); >>>>>>>>>>>>>>时间复杂度O(n)
}
----------------------------------------------------------------------------
}
}
上例中第一条时间复杂度为O(n^2) 第二条路径的时间复杂度为O(n) 所以整段代码的时间复杂度为 max(O(n^2),O(n)) = O(n^2)
1.5 时间复杂度为log n的例子
void sum(int n){
int x = 0 ;
for(int i=1; i<n; i*=2){
x += i;
}
}
代码的运行次数为 2^x = n =>>> x = log n 次
所以上述代码的时间复杂度为O(log n)
1.6 最坏、平均、时间复杂度
我们上述计算的时间复杂度基本上都指的时 最坏的时间复杂度
所以下段代码的 最坏时间复杂度为: O(n)
什么是最好的时间复杂度,我们可以浅显的理解为 需要在数组中找的 x 就是在数组的第一位 所以最好时间复杂度为 O(1)
//在一个数组中查找变量 x 出现的位置,如果找到了,就马上跳出循环,
//返回它的位置值;如果找不到,就返回 -1
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) {
pos = i;
break;
}
}
return pos;
}
最好、最坏情况时间复杂度都是极端情况下的代码复杂度,发生的概率很小
要查找的变量 x 在数组中的位置,总共有 n+1 种情况:在数组的 0~n-1 位置中和不在数组中。我们把每种情况下,查找需要遍历的元素个数累加起来再除以 n+1,就可以得到需要遍历的元素个数的平均值
所以平均时间复杂度为:O((1+2+3+......n+1)/n+1 ) =O( n(n+3)/2(n+1) )= O(n/2 ) = O(n)
所以平均时间复杂度也叫加权平均时间复杂度(亦称为期望时间复杂度)
// array 表示一个长度为 n 的数组
// 代码中的 array.length 就等于 n
//往一个数组中插入数据的功能,当数组满了以后,
//也就是 count == array.length 的时候,我们用 for 循环遍历数组求和,
//再将新的数据插入
int[] array = new int[n];
int count = 0;
void insert(int val) {
if (count == array.length) {
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum = sum + array[i];
}
array[0] = sum;
count = 1;
}
array[count] = val;
++count;
}
上述例子中
最坏时间复杂度为 O(n) 最好时间复杂度为 O(1) 平均时间复杂度为:因为每次可以插入的几率都为 1/n+1 所以平均时间复杂度为 O( (n+1) / (n+1) ) = O(1)
浙公网安备 33010602011771号