这段代码的时间和空间复杂度是多少?

Posted

技术标签:

【中文标题】这段代码的时间和空间复杂度是多少?【英文标题】:what is the time & space complexity in this code? 【发布时间】:2022-01-13 13:33:36 【问题描述】:
int special(const int* array, int p, int r) 
    if (p == r) 
        return 0;
    
    int sum = 0;
    for (int i = p; i < r; i += 1) 
        sum += array[i];
    
    int q = (p + r) / 2;
    return sum + special(array, p, q) + special(array, q + 1, r);

我想知道这段代码的时间和空间复杂度。

我认为时间复数是 Tn = 1 + Tn/2 + Tn/2,所以答案是 Tn = 2n -1 ,但答案是 O(nlogn)

谁知道解决方案?

【问题讨论】:

【参考方案1】:

您的 Tn 复发率有点偏。

确实,您递归处理了两个大小子问题。但是,除了递归之外,您在每个函数调用中所做的工作不是 O(1):您遍历从 p 到 r 的数组部分。因为每个函数调用只与 r-p 成比例地工作,我们应该取输入大小 n = r-p。或者等效地,我们可以将每个递归调用视为接收以索引 [p, r) 为界的大小为 n 的子数组。在任何一种情况下,每个函数调用中的工作,由从 p 到 r 的 for 循环表示,是 O(n),而不是 O(1)。 所以递归是:

T(n) = 2T(n/2) + n

这与表示标准排序算法(如 mergeSort 或 quickSort)复杂性的重复出现相同,这可能已经提示您为什么总时间为 O(nlogn)。

了解这种递归如何导致 nlogn 复杂性的一种方法是考虑递归树。

在顶层,有 1 个函数调用完成 O(n) 的工作。

在第二级,有 2 个函数调用,每个都做 O(n/2) 的工作。总工作量 = 2*O(n/2) = O(n)

在第三层,有 4 个函数调用,每个函数都做 O(n/4) 的工作。总工作量 = 4 * O(n/4) = O(n) ... 等等

O(n) 工作在树的每一层完成,直到达到基本情况并且递归停止。因为子问题的大小在每次迭代中被一分为二,直到它达到 0 并停止递归,所以在递归停止之前大约有 log(n) 个级别,使整体复杂度为 O(n)*log(n) = O( nlogn)

然而,空间复杂度只有 log(n),因为每个函数调用只使用 O(1) 空间(因为您传递一个指针和两个索引,而不是数组的副本)。由于调用堆栈可以获得 log(n) 深度递归调用,总空间 = O(1)*log(n) = O(logn)

【讨论】:

以上是关于这段代码的时间和空间复杂度是多少?的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 241 的时间和空间复杂度是多少。添加括号的不同方法?

FP-Growth 算法的时间和空间复杂度是多少?

时间复杂度与空间复杂度

算法的时间复杂度和空间复杂度

python排序的空间复杂度是多少?

时间复杂度和空间复杂度