本文翻译自:How to find time complexity of an algorithm
The Question 问题
How to find time complexity of an algorithm? 如何找到算法的时间复杂度?
What have I done before posting a question on SO ? 在发布SO问题之前我做了什么?
I have gone through this , this and many other links 我经历了这个 , 这个和许多其他链接
But no where I was able to find a clear and straight forward explanation for how to calculate time complexity. 但是,在任何地方我都无法找到关于如何计算时间复杂度的清晰直接的解释。
What do I know ? 我知道什么 ?
Say for a code as simple as the one below: 说一个简单的代码如下:
char h = 'y'; // This will be executed 1 time
int abc = 0; // This will be executed 1 time
Say for a loop like the one below: 说一个像下面这样的循环:
for (int i = 0; i < N; i++) {
Console.Write('Hello World !');
}
int i=0; int i = 0; This will be executed only once . 这将仅执行一次 。 The time is actually calculated to i=0
and not the declaration. 时间实际计算为i=0
而不是声明。
i < N; 我<N; This will be executed N+1 times 这将执行N + 1次
i++ ; 我++; This will be executed N times 这将执行N次
So the number of operations required by this loop are 因此,此循环所需的操作数为
{1+(N+1)+N} = 2N+2 {1+(N + 1)+ N} = 2N + 2
Note: This still may be wrong, as I am not confident about my understanding on calculating time complexity 注意:这仍然可能是错误的,因为我对自己对计算时间复杂度的理解并不自信
What I want to know ? 我想知道什么?
Ok, so these small basic calculations I think I know, but in most cases I have seen the time complexity as 好的,我想我知道这些小的基本计算,但是在大多数情况下,我认为时间复杂度为
O(N), O(n2), O(log n), O(n!) .... and many other , O(N),O(n2),O(log n),O(n!) .... 等
Can anyone help me understand how does one calculate time complexity of an algorithm? 谁能帮助我了解如何计算一种算法的时间复杂度? I am sure there are plenty of newbies like me wanting to know this. 我相信有很多像我这样的新手想知道这一点。
#1楼
参考:https://stackoom.com/question/kHvj/如何找到算法的时间复杂度
#2楼
How to find time complexity of an algorithm 如何找到算法的时间复杂度
You add up how many machine instructions it will execute as a function of the size of its input, and then simplify the expression to the largest (when N is very large) term and can include any simplifying constant factor. 您将根据输入大小来执行多少条机器指令,然后将表达式简化为最大(当N非常大时)项,并且可以包括任何简化的常数因子。
For example, lets see how we simplify 2N + 2
machine instructions to describe this as just O(N)
. 例如,让我们看看如何简化2N + 2
机器指令以将其描述为O(N)
。
Why do we remove the two 2
s ? 为什么我们删除两个2
s?
We are interested in the performance of the algorithm as N becomes large. 随着N变大,我们对算法的性能感兴趣。
Consider the two terms 2N and 2. 考虑两个项2N和2。
What is the relative influence of these two terms as N becomes large? 随着N变大,这两个项的相对影响是什么? Suppose N is a million. 假设N是一百万。
Then the first term is 2 million and the second term is only 2. 那么第一项是200万,第二项只有2。
For this reason, we drop all but the largest terms for large N. 因此,对于大的N,我们除最大项外都舍弃了所有项。
So, now we have gone from 2N + 2
to 2N
. 因此,现在我们从2N + 2
变为2N
。
Traditionally, we are only interested in performance up to constant factors . 传统上,我们只对直到恒定因素的性能感兴趣。
This means that we don't really care if there is some constant multiple of difference in performance when N is large. 这意味着当N很大时,我们实际上并不关心性能差异是否存在恒定的倍数。 The unit of 2N is not well-defined in the first place anyway. 最初,2N的单位定义不明确。 So we can multiply or divide by a constant factor to get to the simplest expression. 因此,我们可以乘以或除以一个常数因子以获得最简单的表达式。
So 2N
becomes just N
. 所以2N
变成N
#3楼
This is an excellent article : http://www.daniweb.com/software-development/computer-science/threads/13488/time-complexity-of-algorithm 这是一篇很棒的文章: http : //www.daniweb.com/software-development/computer-science/threads/13488/time-complexity-of-algorithm
The below answer is copied from above (in case the excellent link goes bust) 下面的答案是从上面复制的(如果优秀的链接破产了)
The most common metric for calculating time complexity is Big O notation. 用于计算时间复杂度的最常见指标是Big O表示法。 This removes all constant factors so that the running time can be estimated in relation to N as N approaches infinity. 这消除了所有恒定因素,因此当N接近无穷大时,可以相对于N估算运行时间。 In general you can think of it like this: 通常,您可以这样认为:
statement;
Is constant. 是不变的。 The running time of the statement will not change in relation to N. 语句的运行时间不会相对于N改变。
for ( i = 0; i < N; i++ )
statement;
Is linear. 是线性的。 The running time of the loop is directly proportional to N. When N doubles, so does the running time. 循环的运行时间与N成正比。当N加倍时,运行时间也成正比。
for ( i = 0; i < N; i++ ) {
for ( j = 0; j < N; j++ )
statement;
}
Is quadratic. 是二次方的。 The running time of the two loops is proportional to the square of N. When N doubles, the running time increases by N * N. 两个循环的运行时间与N的平方成正比。当N翻倍时,运行时间增加N *N。
while ( low <= high ) {
mid = ( low + high ) / 2;
if ( target < list[mid] )
high = mid - 1;
else if ( target > list[mid] )
low = mid + 1;
else break;
}
Is logarithmic. 是对数的。 The running time of the algorithm is proportional to the number of times N can be divided by 2. This is because the algorithm divides the working area in half with each iteration. 该算法的运行时间与N可以除以2的次数成正比。这是因为该算法在每次迭代中将工作区域划分为一半。
void quicksort ( int list[], int left, int right )
{
int pivot = partition ( list, left, right );
quicksort ( list, left, pivot - 1 );
quicksort ( list, pivot + 1, right );
}
Is N * log ( N ). 是N * log(N)。 The running time consists of N loops (iterative or recursive) that are logarithmic, thus the algorithm is a combination of linear and logarithmic. 运行时间由N个对数的循环(迭代或递归)组成,因此该算法是线性和对数的组合。
In general, doing something with every item in one dimension is linear, doing something with every item in two dimensions is quadratic, and dividing the working area in half is logarithmic. 通常,对一维中的每个项目执行某项操作是线性的,对二维中每一个项目执行某项操作是二次项,将工作区域分为两半是对数的。 There are other Big O measures such as cubic, exponential, and square root, but they're not nearly as common. 还有其他大O度量,例如立方,指数和平方根,但它们并不常见。 Big O notation is described as O ( ) where is the measure. 大O表示法描述为O(),这里的小数位数。 The quicksort algorithm would be described as O ( N * log ( N ) ). 快速排序算法将描述为O(N * log(N))。
Note that none of this has taken into account best, average, and worst case measures. 请注意,所有这些都未考虑最佳,平均和最坏情况下的度量。 Each would have its own Big O notation. 每个都有自己的Big O表示法。 Also note that this is a VERY simplistic explanation. 另请注意,这是一个非常简单的解释。 Big O is the most common, but it's also more complex that I've shown. 大O是最常见的,但是我已经展示过它更加复杂。 There are also other notations such as big omega, little o, and big theta. 还有其他符号,例如大欧米茄,小o和大theta。 You probably won't encounter them outside of an algorithm analysis course. 在算法分析课程之外,您可能不会遇到它们。 ;) ;)
#4楼
O(n) is big O notation used for writing time complexity of an algorithm. O(n)是大的O符号,用于写算法的时间复杂度。 When you add up the number of executions in an algoritm you'll get an expression in result like 2N+2, in this expression N is the dominating term(the term having largest effect on expression if its value increases or decreases). 当您将算法中的执行次数加起来时,您将得到一个表达式,其结果类似于2N + 2,在该表达式中N是主要术语(该术语会增加或减小其值对表达式的影响最大)。 Now O(N) is the time comlexity while N is dominating term. 现在O(N)是时间复杂度,而N是主导项。 Example 例
For i= 1 to n;
j= 0;
while(j<=n);
j=j+1;
here total number of executions for inner loop are n+1 and total number of executions for outer loop are n(n+1)/2, so total number of executions for whole algorithm are n+1+n(n+1/2) = (n^2+3n)/2. 这里,内部循环的执行总数为n + 1,外部循环的执行总数为n(n + 1)/ 2,因此整个算法的执行总数为n + 1 + n(n + 1/2) )=(n ^ 2 + 3n)/ 2。 here n^2 is the dominating term so the time complexity for this algorithm is O(n^2) 这里n ^ 2是主导项,因此该算法的时间复杂度为O(n ^ 2)
#5楼
Taken from here - Introduction to Time Complexity of an Algorithm 摘自此处- 算法时间复杂度简介
1. Introduction 1.简介
In computer science, the time complexity of an algorithm quantifies the amount of time taken by an algorithm to run as a function of the length of the string representing the input. 在计算机科学中,算法的时间复杂度根据代表输入的字符串的长度来量化算法运行所花费的时间。
2. Big O notation 2.大O符号
The time complexity of an algorithm is commonly expressed using big O notation, which excludes coefficients and lower order terms. 算法的时间复杂度通常使用大O表示法表示,其中不包括系数和低阶项。 When expressed this way, the time complexity is said to be described asymptotically, ie, as the input size goes to infinity. 当以这种方式表示时,时间复杂度被称为渐近描述,即,随着输入大小达到无穷大。
For example, if the time required by an algorithm on all inputs of size n is at most 5n 3 + 3n, the asymptotic time complexity is O(n 3 ). 例如,如果算法在大小为n的所有输入上所需的时间最多为5n 3 + 3n,则渐近时间复杂度为O(n 3 )。 More on that later. 以后再说。
Few more Examples: 其他几个例子:
- 1 = O(n) 1 = O(n)
- n = O(n 2 ) n = O(n 2 )
- log(n) = O(n) log(n)= O(n)
- 2 n + 1 = O(n) 2 n +1 = O(n)
3. O(1) Constant Time: 3. O(1)恒定时间:
An algorithm is said to run in constant time if it requires the same amount of time regardless of the input size. 如果算法需要相同的时间量,则无论输入大小如何,都可以说算法以恒定的时间运行。
Examples: 例子:
- array: accessing any element 数组:访问任何元素
- fixed-size stack: push and pop methods 固定大小的堆栈:push和pop方法
- fixed-size queue: enqueue and dequeue methods 固定大小的队列:入队和出队方法
4. O(n) Linear Time 4. O(n)线性时间
An algorithm is said to run in linear time if its time execution is directly proportional to the input size, ie time grows linearly as input size increases. 如果算法的时间执行与输入大小成正比,则称该算法以线性时间运行,即时间随着输入大小的增加而线性增长。
Consider the following examples, below I am linearly searching for an element, this has a time complexity of O(n). 考虑下面的示例,下面我线性搜索一个元素,它的时间复杂度为O(n)。
int find = 66;
var numbers = new int[] { 33, 435, 36, 37, 43, 45, 66, 656, 2232 };
for (int i = 0; i < numbers.Length - 1; i++)
{
if(find == numbers[i])
{
return;
}
}
More Examples: 更多示例:
- Array: Linear Search, Traversing, Find minimum etc 数组:线性搜索,遍历,查找最小值等
- ArrayList: contains method ArrayList:包含方法
- Queue: contains method 队列:包含方法
5. O(log n) Logarithmic Time: 5. O(log n)对数时间:
An algorithm is said to run in logarithmic time if its time execution is proportional to the logarithm of the input size. 如果算法的时间执行与输入大小的对数成正比,则称该算法以对数时间运行。
Example: Binary Search 示例: 二进制搜索
Recall the "twenty questions" game - the task is to guess the value of a hidden number in an interval. 回想一下“二十个问题”游戏-任务是猜测间隔中隐藏数字的值。 Each time you make a guess, you are told whether your guess is too high or too low. 每次您进行猜测时,都会告诉您您的猜测是太高还是太低。 Twenty questions game implies a strategy that uses your guess number to halve the interval size. 二十个问题的游戏蕴含一种策略,该策略使用您的猜测数字将间隔大小减半。 This is an example of the general problem-solving method known as binary search 这是称为二分查找的一般问题解决方法的示例
6. O(n2) Quadratic Time 6. O(n2)二次时间
An algorithm is said to run in quadratic time if its time execution is proportional to the square of the input size. 如果算法的时间执行与输入大小的平方成正比,则称该算法以二次时间运行。
Examples: 例子:
7. Some Useful links 7.一些有用的链接
#6楼
Time complexity with examples 时间复杂度示例
1 - Basic Operations (arithmetic, comparisons, accessing array's elements, assignment) : The running time is always constant O(1) 1-基本操作(算术,比较,访问数组的元素,分配):运行时间始终为常数O(1)
Example : 范例:
read(x) // O(1)
a = 10; // O(1)
a = 1.000.000.000.000.000.000 // O(1)
2 - If then else statement: Only taking the maximum running time from two or more possible statements. 2-如果则else语句:仅从两个或多个可能的语句中获取最大运行时间。
Example: 例:
age = read(x) // (1+1) = 2
if age < 17 then begin // 1
status = "Not allowed!"; // 1
end else begin
status = "Welcome! Please come in"; // 1
visitors = visitors + 1; // 1+1 = 2
end;
So, the complexity of the above pseudo code is T(n) = 2 + 1 + max(1, 1+2) = 6. Thus, its big oh is still constant T(n) = O(1). 因此,上述伪代码的复杂度为T(n)= 2 +1 + max(1,1 + 2)=6。因此,其大oh仍为常数T(n)= O(1)。
3 - Looping (for, while, repeat): Running time for this statement is the number of looping multiplied by the number of operations inside that looping. 3-循环(重复执行):此语句的运行时间是循环数乘以该循环内的操作数。
Example: 例:
total = 0; // 1
for i = 1 to n do begin // (1+1)*n = 2n
total = total + i; // (1+1)*n = 2n
end;
writeln(total); // 1
So, its complexity is T(n) = 1+4n+1 = 4n + 2. Thus, T(n) = O(n). 因此,其复杂度为T(n)= 1 + 4n + 1 = 4n +2。因此,T(n)= O(n)。
4 - Nested Loop (looping inside looping): Since there is at least one looping inside the main looping, running time of this statement used O(n^2) or O(n^3). 4-嵌套循环(循环内循环):由于主循环内至少有一个循环,因此该语句的运行时间使用O(n ^ 2)或O(n ^ 3)。
Example: 例:
for i = 1 to n do begin // (1+1)*n = 2n
for j = 1 to n do begin // (1+1)n*n = 2n^2
x = x + 1; // (1+1)n*n = 2n^2
print(x); // (n*n) = n^2
end;
end;
Common Running Time 普通运行时间
There are some common running times when analyzing an algorithm: 分析算法时,有一些常见的运行时间:
O(1) – Constant Time Constant time means the running time is constant, it's not affected by the input size . O(1)–恒定时间恒定时间表示运行时间是恒定的, 不受输入大小的影响 。
O(n) – Linear Time When an algorithm accepts n input size, it would perform n operations as well. O(n)–线性时间当算法接受n个输入大小时,它也会执行n次操作。
O(log n) – Logarithmic Time Algorithm that has running time O(log n) is slight faster than O(n). O(log n)–具有运行时间O(log n)的对数时间算法比O(n)稍快。 Commonly, algorithm divides the problem into sub problems with the same size. 通常,算法将问题分为相同大小的子问题。 Example: binary search algorithm, binary conversion algorithm. 示例:二进制搜索算法,二进制转换算法。
O(n log n) – Linearithmic Time This running time is often found in "divide & conquer algorithms" which divide the problem into sub problems recursively and then merge them in n time. O(n log n)–线性运算时间该运行时间通常在“分而治之算法”中找到,该算法将问题递归地划分为子问题,然后在n时间内合并它们。 Example: Merge Sort algorithm. 示例:合并排序算法。
O(n 2 ) – Quadratic Time Look Bubble Sort algorithm! O(n 2 )–二次时间看气泡排序算法!
O(n 3 ) – Cubic Time It has the same principle with O(n 2 ). O(n 3 )–立方时间它与O(n 2 )具有相同的原理。
O(2 n ) – Exponential Time It is very slow as input get larger, if n = 1000.000, T(n) would be 21000.000. O(2 n )–指数时间随着输入变大,这非常慢,如果n = 1000.000,则T(n)为21000.000。 Brute Force algorithm has this running time. 蛮力算法具有此运行时间。
O(n!) – Factorial Time THE SLOWEST !!! O(n!)–阶乘时间最慢! Example : Travel Salesman Problem (TSP) 示例:旅行推销员问题(TSP)
Taken from this article . 摘自本文 。 Very well explained should give a read. 很好的解释应该给读。