leetcode 50. Pow(x, n) 中等
要特别注意 n 的范围 ,如果 n = -2^31,使用int 是不可以直接 n = -n; 的
一、使用long
这里做的时候没注意到已经使用了pow,所以这题可以说使用long做出来
class Solution {
public:
double myPow(double x, int n) {
if(x == 0) return 0;
if(n == 0) return 1;
if(n == 1) return x;
if(x == 1) return 1;
long nTemp = n;
if(nTemp < 0){
x = 1.0/x;
nTemp = -nTemp;
}
double res = 1.0;
long count = 0;
vector<double> mult;
mult.push_back(x);
//比如n = 35,那么两两平方的次数为log(35)向下取整
//x^1 x^2 x^4 x^8 x^16 x^32 最多平方5次
int log2 = (int)(log(nTemp)/log(2));
for(int i = 0;i < log2;i++){
double t = mult.back();
mult.push_back(t*t);
}
int size = mult.size();
for(int i = size-1;i >= 0;i--){
if(count + pow(2,i) <= nTemp){
res *= mult[i];
count += pow(2,i); //count代表目前res=x^count
//没留意到这里已经使用了pow,属于违反条件了
}
}
return res;
}
};
二、不使用long
不使用long就要对边界条件单防了。
class Solution {
public:
//单独计算小范围的2^n
int pow2(int n){
if(n == 0) return 1;
int res = 1;
while(n > 0){
res *= 2;
n--;
}
return res;
}
double myPow(double x, int n) {
if(x == 0) return 0;
if(n == 0) return 1;
if(n == 1) return x;
if(x == 1) return 1;
if(x == -1){
if(n == INT_MIN) return 1;
if(n < 0) n = -n;
if(n%2==0) return 1;
else return -1;
}
if(n == INT_MIN){
if(abs(x)>1) return 0;
return (1.0/x)*myPow(1.0,INT_MAX);
}
if(n < 0){
x = 1.0/x;
n = -n;
}
double res = 1.0;
int count = 0;
vector<double> mult;
mult.push_back(x);
int log2 = (int)(log(n)/log(2));
for(int i = 0;i < log2;i++){
double t = mult.back();
mult.push_back(t*t);
}
int size = mult.size();
for(int i = size-1;i >= 0;i--){
if(count + pow2(i) <= n){
res *= mult[i];
count += pow2(i);
}
}
return res;
}
};
我的这种用vector来保存2^k次方的做法对内存消耗还是很大的
以上两种解都是不知不觉就使用了pow的违规解。
一、快速幂 + 递归
class Solution {
public:
double quickMult(double x,long n){
if(n == 0) return 1;
double y = quickMult(x,n/2);
if(n % 2 == 0) return y*y;
else return y*y*x;
}
double myPow(double x, int n){
long N = n;
return N > 0 ? quickMult(x,N) :quickMult(1.0/x,-N);
}
};
二、快速幂 + 迭代
我原本的做法跟这个有点类似,我使用vector本质就是想把这里说的有贡献的2^k次方保存起来
这个方法的关键就是 , 根据 n 的二进制 ,1 的位置所代表的次方就是有贡献的
class Solution {
public:
double quickMult(double x,long n){
if(n == 0) return 1;
if(x == 1) return 1;
if(x == 0) return 0;
double res = 1.0;
double x_contribute = x;
while(n > 0){
if(n % 2 == 1) res *= x_contribute; //如果目前 n 对应的二进制最低位为 1 ,那么res乘上这次的x_contribute
x_contribute *= x_contribute;
n /= 2;
}
return res;
}
double myPow(double x, int n){
long N = n;
return N > 0 ? quickMult(x,N) :quickMult(1.0/x,-N);
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)