问题
如何找到算法的时间复杂度?
在 SO 上发布问题之前我做了什么?
但是,我没有能够找到关于如何计算时间复杂度的明确而直接的解释。
我知道什么 ?
假设代码如下所示:
char h = 'y'; // This will be executed 1 time
int abc = 0; // This will be executed 1 time
说一个像下面这样的循环:
for (int i = 0; i < N; i++) {
Console.Write('Hello World !');
}
int i = 0;这只会执行一次 。实际上,时间计算为i=0
而不是声明。
我 < N;这将执行N + 1次
i ++;这将被执行N次
所以这个循环所需的操作数量是
{1+(N + 1)+ N} = 2N + 2
注意:这仍然可能是错误的,因为我对计算时间复杂度的理解没有信心
我想知道什么?
好吧,所以这些小基本计算我想我知道,但在大多数情况下,我已经看到了时间复杂度
O(N),O(N2),O(log n)的,为 O(n!)......和许多其他 ,
任何人都可以帮我理解如何计算算法的时间复杂度?我相信有很多像我这样的新手想知道这一点。
这是一篇很好的文章: http : //www.daniweb.com/software-development/computer-science/threads/13488/time-complexity-of- algorithm
以下答案是从上面复制的(如果优秀的链接破灭)
计算时间复杂度的最常用指标是 Big O 表示法。这消除了所有常数因子,因此当 N 接近无穷大时,可以相对于 N 估计运行时间。一般来说,你可以这样想:
statement;
是不变的。声明的运行时间不会相对于 N 而改变。
for ( i = 0; i < N; i++ )
statement;
是线性的。循环的运行时间与 N 成正比。当 N 加倍时,运行时间也是如此。
for ( i = 0; i < N; i++ ) {
for ( j = 0; j < N; j++ )
statement;
}
是二次的。两个循环的运行时间与 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;
}
是对数的。算法的运行时间与 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 );
}
是 N * log(N)。运行时间由对数的 N 个循环(迭代或递归)组成,因此算法是线性和对数的组合。
一般来说,对一个维度中的每个项目执行某些操作是线性的,对二维中的每个项目执行某些操作是二次的,将工作区域分成两半是对数的。还有其他 Big O 指标,如立方,指数和平方根,但它们并不常见。 Big O 表示法被描述为 O(),其中是度量。快速排序算法将被描述为 O(N * log(N))。
请注意,这些都没有考虑最佳,平均和最差情况的措施。每个都有自己的 Big O 表示法。另请注意,这是一个非常简单的解释。 Big O 是最常见的,但它也显示得更复杂。还有其他符号,如大欧米茄,小 o 和大 theta。您可能不会在算法分析课程之外遇到它们。 ;)
如何找到算法的时间复杂度
您可以根据输入的大小计算它将执行多少个机器指令,然后将表达式简化为最大(当 N 非常大)时,可以包含任何简化的常量因子。
例如,让我们看看我们如何简化2N + 2
机器指令,将其描述为O(N)
。
为什么我们删除了两个2
?
当 N 变大时,我们对算法的性能感兴趣。
考虑两个术语 2N 和 2。
当 N 变大时,这两个术语的相对影响是什么?假设 N 是一百万。
然后第一个词是 200 万,第二个词只有 2。
出于这个原因,我们放弃了大 N 的最大条件。
所以,现在我们已经从2N + 2
变为2N
。
传统上,我们只对恒定因素的表现感兴趣。
这意味着当 N 很大时,我们并不在乎是否存在性能差异的恒定倍数。无论如何,2N 的单位首先没有明确定义。因此,我们可以乘以或除以常数因子来得到最简单的表达式。
所以2N
变成了N
摘自此处 - 算法时间复杂度简介
在计算机科学中,算法的时间复杂度量化算法作为表示输入的字符串长度的函数运行所花费的时间量。
算法的时间复杂度通常使用大 O 表示法表示,其不包括系数和低阶项。当以这种方式表达时,时间复杂度被称为渐近地描述,即,随着输入大小变为无穷大。
例如,如果算法对大小为 n 的所有输入所需的时间最多为 5n 3 + 3n,则渐近时间复杂度为 O(n 3 )。稍后会详细介绍。
几个例子:
如果算法需要相同的时间量而不管输入大小如何,则称算法在恒定时间内运行。
例子:
如果算法的时间执行与输入大小成正比,则称算法以线性时间运行,即随着输入大小的增加,时间线性增长。
考虑下面的例子,下面我是线性搜索一个元素,它的时间复杂度为 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;
}
}
更多例子:
如果算法的时间执行与输入大小的对数成比例,则称算法以对数时间运行。
示例: 二进制搜索
回想一下 “二十个问题” 游戏 - 任务是猜测一个区间中隐藏数字的值。每当你猜测时,你会被告知你的猜测是太高还是太低。二十个问题游戏意味着使用您的猜测数量将间隔大小减半的策略。这是称为二分搜索的一般问题解决方法的示例
如果算法的时间执行与输入大小的平方成比例,则称算法以二次时间运行。
例子: