计算算法的时间、空间复杂度

时间复杂度

时间复杂度是一个定性(确定性质而非精确量化)描述算法运行时间的函数。通常根据算法运行时的元素操作数进行评估。

假设每个元素操作花费一个固定的时间来运行,那么算法的实际总运行时间与理论值最多只会相差一个常量系数。推导过程如下:

理论时间复杂度 = 理论上每个单元的执行时间 * 单元数
实际时间复杂度 = (理论上每个单元的执行时间 + 常量) * 单元数

所以 实际时间复杂度 - 理论时间复杂度 = 常量 * 单元数 还是一个常量,所以说两者相差一个常量系数。

由于算法的运行时间与不同的输入有关,所以我们通常说的时间复杂度指最差时间复杂度 -- 给定输入情况下的最大运行时间。

时间复杂度使用『大O符号』表述。『大O符号』又称『渐进符号』—— 用一个函数来描述另一个函数数量级的渐近上界。

举个例子,解决一个规模为 n 的问题所花费的时间(或者所需步骤的数目)可以表示为: T(n)=4n^2-2n+2。当 n增大时, n^2项将开始占主导地位,而其他各项可以被忽略。举例说明:当 n=500, 4n^2 项是 2n 项的1000倍大,因此在大多数场合下,省略后者对表达式的值的影响将是可以忽略不计的。[3]

同理,4n^2 的系数 4 也是可以忽略的。

所以我们说该算法具有 n^2 阶(平方阶)的时间复杂度。

计算示例

char h = 'y'; // 执行 1 次
int abc = 0; // 执行 1 次

for (int i = 0; i < N; i++) {        
    Console.Write('Hello World !');
}

[3]

  • int i=0; 执行 1 次
  • i < N; 执行 N + 1 次
  • i++ ; 执行 N 次

所以循环的总计执行次数:

1+(N+1)+N = 2N+2

忽略最高项的系数和非最高项的其他项,得到算法的时间复杂度: O(N)。

空间复杂度

空间复杂度指算法运行时需要消耗的空间资源(空间资源一般指内存)。与时间复杂度相同,也是使用『大O符号』表述,并一般指最差空间复杂度。

这里将不同类型的储存消耗都看成一个单元,最后理论值与实际值也是只会相差一个常量系数。

例子 1 —— 常数空间复杂度

int square(int a)
{
	return a*a;
}

1 个单元用于储存参数 a,2 个单元用于返回结果 a * a,所以一共消耗 3 个单元。无论 a 如何变化,消耗的都是一个固定值,所以是常量级空间复杂度。

例子 2 —— 线性空间复杂度

int sum(int a[], int n)
{
   int sum = 0, i;
   for(i = 0; i < n; i++)
      sum = sum + a[i];
   return sum;
}
  • 参数 a:n 个单元
  • 参数 n:1 个单元
  • 变量 sum:1 个单元
  • 变量 i:1 个单元

所以一共为 n + 4 个单元,忽略非最高项,所以空间复杂度为 O(n)。

参考

  1. https://en.wikipedia.org/wiki/Time_complexity
  2. https://zh.wikipedia.org/wiki/时间复杂度
  3. https://zh.wikipedia.org/wiki/大O符号
  4. How to find time complexity of an algorithm
    Ask
  5. http://btechsmartclass.com/DS/U1_T3.html
posted @ 2018-06-20 19:46  Jay54520  阅读(565)  评论(0编辑  收藏  举报