什么是时间复杂度和空间复杂度

时间复杂度和空间复杂度

时间复杂度

时间复杂度是评估算法运行时间长短的度量,也叫做渐进时间复杂度。它描述的是随着输入规模 n 的增加,算法运行时间的增长趋势。

常见的时间复杂度有:常数阶 O(1)、对数阶 O(logn)、线性阶 O(n)、线性对数阶 O(nlogn)、平方阶 O(n^2)、立方阶 O(n^3)、…、指数阶 O(2^n)、O(n!)。

通常情况下,我们希望算法的时间复杂度尽可能小,使其能够在较短的时间内处理大规模的数据。

时间复杂度的计算方法

在计算时间复杂度时,通常规定基本操作的执行次数为 1,然后分析算法中基本操作执行次数与数据规模增长之间的关系,从而得出时间复杂度的表达式。

以下是几种常用的时间复杂度计算方法:

  • 外层循环次数乘以内层循环次数,即双重循环的时间复杂度为 O(n^2);
  • 最高次项系数的幂次,即多项式的时间复杂度为 O(n^k),其中 k 为多项式的次数;
  • 递推公式的解析式的时间复杂度,即解递推公式的时间复杂度为 O(f(n))。

时间复杂度的示例说明

下面以快速排序和冒泡排序为例,介绍时间复杂度的计算过程和时间复杂度的比较。

快速排序的平均时间复杂度是 O(nlogn),最坏情况下为 O(n^2),因此快速排序通常比冒泡排序更快。例如,对于一个长度为10000的数组,使用快速排序只需要大约20000次比较,而使用冒泡排序需要大约50000000次比较。

冒泡排序的时间复杂度是 O(n^2),它的计算方法如下:

for (i = 0; i < n; i++) {
    for (j = 0; j < n - i - 1; j++) {
        if (arr[j] > arr[j+1]) {
            swap(arr[j], arr[j+1]);
        }
    }
}

外层循环执行了 n 次,内层循环执行了 n-1 次、n-2 次、…、1 次,因此总共执行了 (n-1)+(n-2)+…+1 = n(n-1)/2 次基本操作,即时间复杂度为 O(n^2)。

空间复杂度

空间复杂度是评估算法空间占用大小的度量,也叫做渐近空间复杂度。

常见的空间复杂度有:常数级空间 O(1)、线性级空间 O(n)、二次空间 O(n^2)、递归空间 O(logn)。

空间复杂度的计算方法

在计算空间复杂度时,通常需要估算算法存储数据所需的占用空间,然后分析空间占用大小与数据规模增长之间的关系,从而得出空间复杂度的表达式。

以下是几种常用的空间复杂度计算方法:

  • 基本数据类型和递归栈占用的空间;
  • 数组、列表、栈、队列等数据结构所需的空间;
  • 递归算法所需的空间。

空间复杂度的示例说明

下面以递归求阶乘和非递归求阶乘为例,介绍空间复杂度的计算过程和空间复杂度的比较。

递归求阶乘的空间复杂度是 O(n),它的计算方法如下:

int factorial(int n) {
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n-1);
    }
}

递归深度为 n,每次递归需要存储参数和返回值,因此总共需要的空间为 n*O(1),即空间复杂度为 O(n)。

非递归求阶乘的空间复杂度是 O(1),它的计算方法如下:

int factorial(int n) {
    int res = 1;
    for (int i = 1; i <= n; i++) {
        res *= i;
    }
    return res;
}

只需要存储一个结果变量和一个循环变量,因此空间复杂度为 O(1)。

总结

时间复杂度和空间复杂度是评估算法性能的重要指标,能够帮助我们选择更高效的算法和优化算法的实现。在编写程序时,我们需要尽可能减少时间复杂度和空间复杂度,以提高程序的性能和效率。