这段代码的时间和空间复杂度是多少?
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)
【讨论】:
以上是关于这段代码的时间和空间复杂度是多少?的主要内容,如果未能解决你的问题,请参考以下文章