大O，您如何计算/近似？Big O, how do you calculate/approximate it?

1， 但是正如他们所说，不要过度使用， 过早的优化是万恶之源 ，而没有正当理由的优化也应该得到这个名字。

23 个回复23

===============>>#1 票数：1457 已采纳

``````int sum(int* data, int N) {
int result = 0;               // 1

for (int i = 0; i < N; i++) { // 2
result += data[i];        // 3
}

return result;                // 4
}
``````

``````Number_Of_Steps = f(N)
``````

``````Number_Of_Steps = f(data.length)
``````

``````f(N) = C + ??? + C
``````

``````f(N) = C + (C + C + ... + C) + C = C + N * C + C
``````

1. 带走所有常数`C`
2. `f()`获得`standard form`多项式
3. 除以多项式的项，然后按增长率对其进行排序。
4. `N`接近`infinity`大时，保持增长的那个。

``````f(N) = 2 * C * N ^ 0 + 1 * C * N ^ 1
``````

``````f(N) = 1 + N ^ 1
``````

``````O(N)
``````

``````for (i = 0; i < 2*n; i += 2) {  // 1
for (j=n; j > i; j--) {     // 2
foo();                  // 3
}
}
``````

``````f(N) = Summation(i from 1 to 2 * N / 2)( ... ) =
= Summation(i from 1 to N)( ... )
``````

``````f(N) = Summation(i from 1 to N)( Summation(j = ???)(  ) )
``````

``````f(N) = Summation(i from 1 to N)( Summation(j = 1 to (N - (i - 1) * 2)( C ) )
``````

（我们假设`foo()``O(1)`并采取`C`步。）

``````f(N) = Summation(i from 1 to N / 2)( Summation(j = 1 to (N - (i - 1) * 2)) * ( C ) ) + Summation(i from 1 to N / 2) * ( C )
``````

1. 求和（w从1到N）（C）= N * C
2. 求和（w从1到N）（A（+/-）B）=求和（w从1到N）（A）（+/-）求和（w从1到N）（B）
3. 求和（w从1到N）（w * C）= C *求和（w从1到N）（w）（C是一个常数，与`w`无关）
4. 求和（w从1到N）（w）=（N *（N + 1））/ 2

``````f(N) = Summation(i from 1 to N / 2)( (N - (i - 1) * 2) * ( C ) ) + (N / 2)( C )

f(N) = C * Summation(i from 1 to N / 2)( (N - (i - 1) * 2)) + (N / 2)( C )

f(N) = C * (Summation(i from 1 to N / 2)( N ) - Summation(i from 1 to N / 2)( (i - 1) * 2)) + (N / 2)( C )

f(N) = C * (( N ^ 2 / 2 ) - 2 * Summation(i from 1 to N / 2)( i - 1 )) + (N / 2)( C )

=> Summation(i from 1 to N / 2)( i - 1 ) = Summation(i from 1 to N / 2 - 1)( i )

f(N) = C * (( N ^ 2 / 2 ) - 2 * Summation(i from 1 to N / 2 - 1)( i )) + (N / 2)( C )

f(N) = C * (( N ^ 2 / 2 ) - 2 * ( (N / 2 - 1) * (N / 2 - 1 + 1) / 2) ) + (N / 2)( C )

=> (N / 2 - 1) * (N / 2 - 1 + 1) / 2 =

(N / 2 - 1) * (N / 2) / 2 =

((N ^ 2 / 4) - (N / 2)) / 2 =

(N ^ 2 / 8) - (N / 4)

f(N) = C * (( N ^ 2 / 2 ) - 2 * ( (N ^ 2 / 8) - (N / 4) )) + (N / 2)( C )

f(N) = C * (( N ^ 2 / 2 ) - ( (N ^ 2 / 4) - (N / 2) )) + (N / 2)( C )

f(N) = C * (( N ^ 2 / 2 ) - (N ^ 2 / 4) + (N / 2)) + (N / 2)( C )

f(N) = C * ( N ^ 2 / 4 ) + C * (N / 2) + C * (N / 2)

f(N) = C * ( N ^ 2 / 4 ) + 2 * C * (N / 2)

f(N) = C * ( N ^ 2 / 4 ) + C * N

f(N) = C * 1/4 * N ^ 2 + C * N
``````

BigOh是：

``````O(N²)
``````

===============>>#2 票数：199

``````int array[n];
``````

``````x = array[0];
``````

``````for(int i = 0; i < n; i++){
if(array[i] == numToFind){ return i; }
}
``````

``````for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
array[j] += 2;
}
}
``````

===============>>#3 票数：95

O（1）-确定数字是偶数还是奇数； 使用恒定大小的查找表或哈希表

O（logn）-使用二进制搜索在排序数组中查找项目

O（n）-在未排序的列表中查找项目； 加两个n位数字

O（n 2 ）-用一个简单的算法将两个n位数字相乘； 加两个n×n矩阵; 气泡排序或插入排序

O（n 3 ）-用简单算法将两个n×n矩阵相乘

O（c n ）-使用动态规划找到旅行商问题的（精确）解； 使用蛮力确定两个逻辑语句是否等效

O（n！）-通过蛮力搜索解决旅行商问题

O（n n ）-通常用于代替O（n！）来得出渐近复杂度的更简单公式

===============>>#4 票数：42

• 最坏的情况（通常不是最简单，但并不总是很有意义）
• 一般情况（通常很难弄清楚...）

• ...

R. Sedgewick和P. Flajolet撰写的《算法分析入门》就是很好的介绍。

===============>>#5 票数：28

``````(define (fac n)
(if (= n 0)
1
(* n (fac (- n 1)))))
``````

1 *（n-1）= O（n）

===============>>#6 票数：26

O（（N / 2 + 1）*（N / 2））= O（N 2/4 + N / 2）= O（N 2/4）= O（n 2）的

O（log N ）<O（ N ）<O（ N log N ）<O（ N 2 ）<O（ N k ）<O（e n ）<O（ n ！）

===============>>#8 票数：20

1. 算术运算（例如+或％）。
2. 逻辑运算（例如&&）。
3. 比较操作（例如，<=）。
4. 结构访问操作（例如，像A [i]这样的数组索引，或者跟随->运算符的指针）。
5. 简单分配，例如将值复制到变量中。
6. 调用库函数（例如scanf，printf）。

1. 在表达式中不包含函数调用的赋值语句。
2. 阅读声明。
3. 编写不需要函数调用来评估参数的语句。
4. 跳转语句中断，继续，转到和返回表达式，其中表达式不包含函数调用。

``````for (i = 0; i < n-1; i++)
{
small = i;
for (j = i+1; j < n; j++)
if (A[j] < A[small])
small = j;
temp = A[small];
A[small] = A[i];
A[i] = temp;
}
``````

``````(1) for (j = 0; j < n; j++)
(2)   A[i][j] = 0;
``````

``````(2) for (i = 0; i < n; i++)
(3)     for (j = 0; j < n; j++)
(4)         A[i][j] = 0;
``````

===============>>#12 票数：8

``````a=0;
b=1;
for (i = 0; i <n; i++) {
tmp = b;
b = a + b;
a = tmp;
}
``````

1 + 2 + 3 + ... + n = n（n-1）/ 2 = O（n ^ 2）

===============>>#17 票数：5

``````int nCmp = 0;
System.Random rnd = new System.Random();

// measure the time required to sort a list of n integers
void DoTest(int n)
{
List<int> lst = new List<int>(n);
for( int i=0; i<n; i++ )
lst[i] = rnd.Next(0,1000);

// as we sort, keep track of the number of comparisons performed!
nCmp = 0;
lst.Sort( delegate( int a, int b ) { nCmp++; return (a<b)?-1:((a>b)?1:0)); }

System.Console.Writeline( "{0},{1}", n, nCmp );
}

// Perform measurement for a variety of sample sizes.
// It would be prudent to check multiple random samples of each size, but this is OK for a quick sanity check
for( int n = 0; n<1000; n++ )
DoTest(n);
``````

===============>>#19 票数：4

f（n）= O（g（n））表示存在正常数c和k，因此对于所有n≥k，0≤f（n）≤cg（n）。 c和k的值必须对于函数f是固定的，并且不得依赖于n。

===============>>#21 票数：2

1. 如果我们有一个术语的总和，则保留增长率最高的术语，而省略其他术语。
2. 如果我们有多个因子的乘积，则常量因子将被忽略。

===============>>#23 票数：1

Big-O只是用来比较程序的复杂性，这意味着输入增加时它们增长的速度，而不是执行该操作所花费的确切时间。