第一个功能: -
void strange (int n,int k)
{
int i;
if(k > n)
return;
for(i=k; i<n; i++)
printf("?");
strange(n, k+2);
return;
}
第二个功能: -
void weird(int n, int k)
{
int i;
if(n <= 0 || (k <= 0))
return;
k *=2;
for(i=0; i < k; i++){
printf("?");
weird(n/2, -n/2 )
}
weird(n/2, k)
return;
}
我很难找到这两个函数的空间或时间的复杂性。我知道我必须在这里使用递归,但我只是不理解递归。我是新手,我的老师也解释得不太好。有一种简单的方法可以使用递归来计算空间和时间的复杂性吗? 你能否告诉我如何处理这类问题?
注意: - 我不是要求完整的答案只是提示和建议。所以请不要误解这篇文章。
答案 0 :(得分:0)
您不使用递归来查找复杂性,您需要在递归中找到复杂性。我想如果我澄清一些事情,你会看到你需要做什么。
<强>递归强>
首先,递归只是一个自我调用的函数。非常直截了当。一个非常简单的递归函数可用于计数:
recursiveCounter(current, max)
{
if(current > max)
return;
printf("%i ", current);
recursiveCounter(current + 1, max);
}
此函数将一直调用自身,直到当前大于最大值,然后返回。
<强>复杂性强>
现在,就你的复杂性而言,你有两个;空间和时间。空间是指您的输入需要多少内存,而时间是您的功能将执行多少次迭代。在我的例子中,空间复杂度是 O(1)(这是常数),而我的时间复杂度将是 O(N)(线性增加)。
另一个例子:
recursiveCounter2(current, max)
{
if(current >= max)
return;
for(int x = 0; x < max; ++X)
{
printf("%i ", current);
}
printf("\n");
recursiveCounter(current + 1, max);
}
此功能每次都会从头开始计入给定的数字。输出如下所示:
max = 5
0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
等等。
将它放在一起
所以,把它分解成几部分:
问。我的递归函数会被调用多少次?
A。由于我的比较(current < max)
和我的线性增长(current + 1)
,我们可以假设它会运行max
次。
问。我会在内部函数中迭代多少次?
A。 for循环也会执行max
次操作。
将所有这些结合在一起,我们将执行max * max
次计算。这使得它成为 O(N ^ 2)算法。因此,如果max为5,我们有5 * 5 = 25次计算。
逐步解决问题是解决问题的最佳方式。
答案 1 :(得分:0)
第一个功能:
你正在运行一个从k到n的循环,在最坏的情况下会从0到n开始(假设k和n总是正数)。
对于每次递归,您将移动两个整数接近完成,运行循环比最后一次少两次。这只会增加复杂性的常数乘数。
基本上,对于最坏的情况,你运行循环n次,然后n-2次,然后n-4次,依此类推。 k对时间复杂度没有影响。如果可以的话,它会减少运行时间,但是大哦符号会丢弃它。
第二功能:
for循环运行k次。 for循环中的函数是无用的,因为它一旦调用就会返回if条件(k的-ve值)。
每次递归时,n减少到一半。要计算这种递归的时间复杂度,您可以考虑它 T(n)= T(n / 2)且T(1)= 1
即。使用值n运行递归所花费的时间与使用值n / 2运行递归所用的时间相同。当n减少到1时,它是O(1)执行。
求解递归方程以获得递归调用的时间复杂度。
函数本身的时间复杂度将是for循环的时间复杂度和递归的时间复杂度的乘积。
空间复杂性: 这两个函数只有整数变量。没有数组/字符串。