我不明白如何通过对O(log n)乘法求平方来进行取幂。
在我看来,你最终做的不仅仅是log n乘法(其中n是指数的大小)。
示例:
power(2,8)
/ \
pow(2,4) * pow(2,4)
/ \ / \
pow(2,2) * pow(2,2) pow(2,2) * pow(2,2)
/ \ / \
p(2,1)*p(2,1) p(2,1)*p(2,1) p(2,1)*p(2,1) p(2,1)*p(2,1)
这是七次乘法,就像常规取幂一样。
以下是我尝试过的3种方法:
long pow(int base, int exp)
{
if(exp == 1)
return base;
else
return base * pow(base, exp-1);
}
long pow2(int base, int exp)
{
if(exp == 1)
return base;
else if(exp == 0)
return 1;
else
if(exp % 2 == 0)
return pow2(base * base, exp/2);
else
return base * pow2(base * base, exp/2) ;
}
long pow3(int base, int exp)
{
if(exp == 1)
return base;
int x = pow2(base,exp/2);
if(exp%2 == 0)
return x*x;
else
return base*x*x;
}
似乎一旦递归到底,就会执行相同数量的乘法......
答案 0 :(得分:3)
您应该只考虑一个分支,因为您保存结果并且不重新计算分支。实际上只完成了以下乘法运算:
power(2,8)
/ \
pow(2,4) [*] pow(2,4)
/ \ / \
pow(2,2) [*] pow(2,2) pow(2,2) * pow(2,2)
/ \ / \
p(2,1)[*]p(2,1) p(2,1)*p(2,1) p(2,1)*p(2,1) p(2,1)*p(2,1)
答案 1 :(得分:2)
你正在显示一个二叉树,但你的递归函数不会自己调用两次,只调用一次,所以它只遍历一个logN路径。
此外,此算法的递归是愚蠢的(缓慢,复杂,脆弱)。 只需遍历指数位:
long pow(long base, int exp) {
long result = 1;
while (exp > 0) {
if (exp & 1) result *= base;
exp >>= 1;
base *= base;
}
return result;
}
答案 2 :(得分:1)
让我们来看看你的考试2 ^ 8。在第一步,你必须计算2 ^ 4。当你得到结果时,只需将其自身相乘。您不必计算整个树,因为您已经知道结果。我们来看看你的示例树。在这种情况下,您只需要计算最左侧的树。这意味着只有2 ^ 4,2 ^ 2,2 ^ 1然后使用结果得到2 ^ 8。
此外,您的功能应该是这样的:
int power(int base, int power) {
if (power == 0)
return 1;
if (power == 1)
return base;
int result = power(base, power / 2);
result *= result;
if (power % 2 == 1)
result *= base;
return result;
}