50. Pow(x,n)
贴个题目:
贴个示例:
解题思路:
这一题,用个开玩笑的做法就是直接return pow(x,n),这是最赖皮的做法。但是题目本来就要求你写一个pow函数,所以我们要用其他方法。
直接遍历是可以的,但是呢,会超出时间限制,因此我们要想一种方法,能够减少时间复杂度。
收到二分法的启发,我们可以进行类似于以下的计算:
x,xx,xxxx……因此就会有递归式:myPow(x*x,n/2)
那么上述的递归式,是n为偶数的情况,当n为奇数的时候又应该怎么样呢?由于n为奇数,因此我们可以先称一个x,将其变成偶数,即:xmyPow(xx,n/2)
到这里我们运行测试就会发现一个问题:当n为负数的时候,计算结果通常是错误的。因此在n为负数的时候我们要把其转化为n为整数的算法,即1/myPow(x,-n)
这种方法思想上是可行的,但是我们看回去题目要求的n的取值范围,就会想到,将负数n转化成正数的时候,数据会溢出int的范围,因此我们可以将-n变成-(n+1),那么就不会数据溢出,但是这么做之后的对应数据处理就应该前面乘多一个x,即:1/(x*myPow(x,-(n+1))),如此就能解决大概在300个测试案例出现时的数据溢出问题
贴个代码:
double myPow(double x, int n){
if(0==n) return 1;
else if(n<0) return 1/(x*myPow(x,-(n+1)));
else if(n>0)
{
if(n%2==1) return x*myPow(x*x,n/2);
else return myPow(x*x,n/2);
}
return 1;
}
性能分析:
时间分析:
时间上,我们运用了类似于二分法的思想,因此时间复杂度为:O(logn)
空间分析:
递归算法的复杂度的计算方法是:
每次递归的空间复杂度*递归深度
注意这里是递归深度,因此通过分析可以知道,这里的递归深度是:O(logn),每一次递归的空间复杂度是:O(1)
综上所述空间复杂度是:O(logn)