一个递归函数调用自己N次少一个的时间复杂度是多少?
What is the time complexity of a recursive function that calls itself N times with one less?
这种结构的递归函数的时间复杂度是多少
void f(int n)
{
if (n == 0)
return;
for (int i = n; i >= 1; --i)
{
// something O(1)
f(n - i);
}
}
我的想法是遵循
T(n) = T(0) + ... + T(n-2) + T(n-1) = (T(0) + ... + T(n-2)) + T(n-1) = T(n-1) + T(n-1) = 2T(n-1)
所以我们会说 O(2^n-1)?
或者是
T(n) = T(0) * ... * T(n-1)
看来你的分析很有道理。
如有疑问,您可以进行测量。如果复杂度真的是 O(2^n)
那么你可以计算内循环执行的频率,并且为了增加 n
计数除以 2^n
应该收敛:
#include <iostream>
struct foo {
int counter = 0;
void f(int n) {
if (n == 0)
return;
for (int i = n; i >= 1; --i) {
++counter;
f(n - i);
}
}
};
int main() {
for (int i=0;i < 4;++i) {
long int n = 2<<i;
foo f;
f.f(n);
std::cout << n << " " << (2<<n) << " " << f.counter / static_cast<double>(2<<n) << "\n";
}
}
输出为:
2 8 0.375
4 32 0.46875
8 512 0.498047
16 131072 0.499992
请注意,此测量值不能证明您的分析是正确的。虽然计数似乎收敛到 0.5
并且测量不能伪造你的分析。计数似乎在 2^n-1
左右,只是对于复杂性而言,常数因子 2
并不重要,您可以将其写为 O(2^n)
.
PS:考虑算法时,复杂性很有趣。在考虑具体实施时,情况有些不同。请注意,编写的函数可以优化为等效的 void f(int) {}
,这显然不是 O(2^n)
.
这种结构的递归函数的时间复杂度是多少
void f(int n)
{
if (n == 0)
return;
for (int i = n; i >= 1; --i)
{
// something O(1)
f(n - i);
}
}
我的想法是遵循
T(n) = T(0) + ... + T(n-2) + T(n-1) = (T(0) + ... + T(n-2)) + T(n-1) = T(n-1) + T(n-1) = 2T(n-1)
所以我们会说 O(2^n-1)?
或者是
T(n) = T(0) * ... * T(n-1)
看来你的分析很有道理。
如有疑问,您可以进行测量。如果复杂度真的是 O(2^n)
那么你可以计算内循环执行的频率,并且为了增加 n
计数除以 2^n
应该收敛:
#include <iostream>
struct foo {
int counter = 0;
void f(int n) {
if (n == 0)
return;
for (int i = n; i >= 1; --i) {
++counter;
f(n - i);
}
}
};
int main() {
for (int i=0;i < 4;++i) {
long int n = 2<<i;
foo f;
f.f(n);
std::cout << n << " " << (2<<n) << " " << f.counter / static_cast<double>(2<<n) << "\n";
}
}
输出为:
2 8 0.375
4 32 0.46875
8 512 0.498047
16 131072 0.499992
请注意,此测量值不能证明您的分析是正确的。虽然计数似乎收敛到 0.5
并且测量不能伪造你的分析。计数似乎在 2^n-1
左右,只是对于复杂性而言,常数因子 2
并不重要,您可以将其写为 O(2^n)
.
PS:考虑算法时,复杂性很有趣。在考虑具体实施时,情况有些不同。请注意,编写的函数可以优化为等效的 void f(int) {}
,这显然不是 O(2^n)
.