今天为大家带来leetcode题库中的第50题——Pow(x,n)
本题要求实现pow(x,n),即计算x的整数n次幂函数。
这道题的实现有多种方法,本次笔者在这里讲述两种常见方法。
方法一:暴力解法,即利用for循环直接进行。
class Solution {
public:
double myPow(double x, int n) {
long long N =n;
if(N<0){
x=1/x;
N=-N;
}
//判断处理n为负数的情况
double ans=1;
for(long long i=0;i<N;i++ )
ans=ans*x;
//利用for循环直接对x连乘n次从而实现算法
return ans;
}
};这种方法非常直观,代码中也给出了相关的注释。但暴力解法在这里的时间复杂度为O(n),和后面的方法相比就比较大,所以很多时候会要求你用复杂度更小的算法而不是直接用暴力解法。
方法二:分而治之,即利用快速幂的方法进行递归操作。
当我们要计算 xn 时,我们可以先递归地计算出 y=x^⌊n/2⌋,其中 ⌊a⌋ 表示对 a 进行下取整;
根据递归计算的结果,如果 n 为偶数,那么 xn=y2;
如果 n 为奇数,那么 xn=y2×x;
递归的边界为 n=0,任意数的 0 次方均为 1。
class Solution {
public:
double quickMul(double x, long long N) {
if (N == 0) {
return 1.0;
}
double y = quickMul(x, N / 2);
return N % 2 == 0 ? y * y : y * y * x;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};
来源:leetcode官方题解
本次递归的方法时间复杂度为O(log n),空间复杂度为O(log n)。
ps:我们在方法二中也可以用迭代的方法
class Solution {
public:
double quickMul(double x, long long N) {
double ans = 1.0;
// 贡献的初始值为 x
double x_contribute = x;
// 在对 N 进行二进制拆分的同时计算答案
while (N > 0) {
if (N % 2 == 1) {
// 如果 N 二进制表示的最低位为 1,那么需要计入贡献
ans *= x_contribute;
}
// 将贡献不断地平方
x_contribute *= x_contribute;
// 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
N /= 2;
}
return ans;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};
来源:leetcode官方题解
迭代方法下时间复杂度为O(logn),空间复杂度为O(1)。
上述几种方法重点理解后面两种,迭代和递归的思想十分重要。
默认评论
Halo系统提供的评论