当我尝试递归计算2 ^ 8时,我不知道这种方法将如何使用31次。
此方法是否计算O(logN)复杂度的功率?
当我运行它时,输出是:
0
1
2
3
4
5
...
29
30
2^8 is: 256
代码
private static int power(int x, int y)
{
System.out.println(step++);
if (y == 0)
return 1;
return power(x, y/2) * power(x, y/2);
}
答案 0 :(得分:6)
在这里,您实际上是使用相同的值对power方法进行两次调用:
return power(x, y/2) * power(x, y/2);
相反,如果你这样写,你可以拨打一半的电话:
int toReturn = power(x, y/2);
return toReturn * toReturn;
如果我们完成您的原始示例,我们将进行31次调用,这就是您所看到的(0到30)。浏览您的代码以了解原因:
power(2, 8)
power(2, 4)
power(2, 4)
power(2, 2)
power(2, 2)
power(2, 2)
power(2, 2)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
答案 1 :(得分:2)
正如其他海报所指出的那样,你经常调用power
方法。我只是想添加(我不想这样做作为注释),我不建议使用静态变量来计算递归的级别。相反,我建议将当前步骤作为另一个参数传递给函数:
private static int power(int x, int y, int recursiveCallStep)
{
System.out.println(recursiveCallStep++);
if (y == 0)
return 1;
int toReturn = power(x, y/2, recursiveCallStep);
return toReturn * toReturn;
}
第一个电话会是:
int result = power(2, 8, 0);
如果你以前做过这件事,你就会意识到同一个步数不止一次输出。
答案 2 :(得分:1)
不,它不是O(logN),它是O(NlogN)
在每次迭代中,您创建的问题只有问题的一半(这很好),但您正在创建其中两个。
你应该这样做,而不是
return power(x, y/2) * power(x, y/2);
此
int power = power(x, y/2);
return power * power;
答案 3 :(得分:0)
完全没有必要使用除草树。这就是为什么你的代码重新计算不止一次相同值的原因。
使用这个更简单的递归代码可以获得更好的复杂性:(你可以看到它是O(N))
private static int power(int x, int y)
{
System.out.println(step++);
if (y == 0)
return 1;
else
{
return x * power(x, y - 1);
}
}
当X = 2且Y = 3时,堆栈跟踪将为:
power(2,3) = 2 * power(2, 2);
power(2,2) = 2 * power(2, 1);
power(2,1) = 2 * power(2, 0);
power(2,0) = 1;