[LeetCode]Pow(x, n)
原创
©著作权归作者所有:来自51CTO博客作者byamao1的原创作品,请联系作者获取转载授权,否则将追究法律责任
Question
Implement pow(x, n).
本题难度Medium。
【复杂度】
时间 O(log(N)) 空间 O(1)
【思路】
分治法。
【代码】
public class Solution {
public double myPow(double x, int n) {
//require
if(n==0)
return 1.0;
//invariant
if(n<0)
return 1.0/pow(x,-(long)n);
else
return pow(x,n);
}
private double pow(double x,long n){
//bound
if(n==1)
return x;
double v=pow(x,n/2);
if(n%2==1)
return v*v*x;
else
return v*v;
}
}
【注意】
你觉得代码可以这样写吗:
public class Solution {
public double myPow(double x, int n) {
//require
if(n==0)
return 1.0;
//invariant
if(n<0)
return 1.0/pow(x,-n); //wrong
else
return pow(x,n);
}
private double pow(double x,int n){
//bound
if(n==1)
return x;
double v=pow(x,n/2);
if(n%2==1)
return v*v*x;
else
return v*v;
}
}
这么写,会在n=INT_MIN时出错!
当n=INT_MIN
也就是-10^31
时,第8行的-n
得到的结果仍然是INT_MIN
:
如果 INT_MIN=0x80000000 也就是-10^31
要注意!!!-INT_MIN 不是等于 10^31
要严格按照计算机的计算负数的过程,先取反,再加1
0x80000000 -取反-> 0x7FFFFFFF -加1-> 0x80000000
结果是:
-INT_MIN=INT_MIN
也就是说pow函数的参数n输入的是INT_MIN
,这样就必然出错(它是负数,而pow函数不能处理负数)。要避免它就要在第8行将n
转换为long
。不过别写错了,不是(long)-n
,这样得到的结果是-10^31
;应该写成-(long)n
,得到的结果是10^31
。
【附】
也有的答案是这样的:
public class Solution {
public double myPow(double x, int n) {
//require
if(n==0)
return 1.0;
//invariant
if(n<0)
return 1.0/pow(x,-n);
else
return pow(x,n);
}
private double pow(double x,int n){
//bound
if(n==0)
return 1;
double v=pow(x,n/2);
if(n%2==0)
return v*v;
else
return v*v*x;
}
}
为什么它没有把n转换为long呢?
1、它的pow函数可以处理负数
2、-INT_MIN=INT_MIN
保证了数值没有变化。如果-INT_MIN
不等于INT_MIN
,那它就错了。
你把第8行return 1.0/pow(x,-n);
改为return 1.0/pow(x,n);
照样可以。实际上更为好的代码就是这样的:
public class Solution {
public double myPow(double x, int n) {
//require
if(n==0)
return 1.0;
//invariant
if(n<0)
return 1.0/pow(x,n); //-n改为n
else
return pow(x,n);
}
private double pow(double x,int n){
//bound
if(n==0)
return 1;
double v=pow(x,n/2);
if(n%2==0)
return v*v;
else
return v*v*x;
}
}
感谢エリザベス兄弟给予的无私支持!!