mysql中如何幂次方的函数_幂次方的四种快速取法(不使用pow函数)

Pow(x, n)

方法一:暴力法

方法二:递归快速幂算法

方法三:迭代快速幂算法

方法四:位运算法

方法一:暴力法

思路

只需模拟将 x 相乘 n 次的过程。

如果 \(n < 0\),我们可以直接用 \(\dfrac{1}{x}\), \(-n\) 来替换 \(x , n\) 以保证 \(n \ge 0\)。该限制可以简化我们的进一步讨论。

但我们需要注意极端情况,尤其是负整数和正整数的不同范围限制。

算法

我们可以用一个简单的循环来计算结果。

class Solution {

public:

double myPow(double x, int n) {

long long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

double ans = 1;

for (long long i = 0; i < N; i++)

ans = ans * x;

return ans;

}

};

复杂度分析

时间复杂度:\(O(n)\)。我们将 x 相乘 n 次。

空间复杂度:\(O(1)\)。我们需要一个变量来存储 x 的最终结果。

方法二:递归快速幂算法

e7e4271e855d040ec486b75e8998d1df.png

class Solution {

public:

double fastPow(double x, long long n) {

if (n == 0) {

return 1.0;

}

double half = fastPow(x, n / 2);

if (n % 2 == 0) {

return half * half;

} else {

return half * half * x;

}

}

double myPow(double x, int n) {

long long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

return fastPow(x, N);

}

};

复杂度分析

时间复杂度:O(log(n))O(log(n))。每次我们应用公式$ (x ^ n) ^ 2 = x ^ {2 * n}\(,\)n$ 就减少一半。 因此,我们最多需要 \(O(log(n))\)次计算来得到结果。

空间复杂度:\(O(log(n))\)。每次计算,我们都需要存储 \(x ^ {n / 2}\) 的结果。 我们需要计算 \(O(log(n))\)次,因此空间复杂度为 \(O(log(n))\)。

方法三:迭代快速幂算法

c29df0f98476fe734df51a5cfc45ade8.png

递归或迭代的快速幂实际上是实现同一目标的不同方式。

class Solution {

public:

double myPow(double x, int n) {

long long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

double ans = 1;

double current_product = x;

for (long long i = N; i ; i /= 2) {

if ((i % 2) == 1) {

ans = ans * current_product;

}

current_product = current_product * current_product;

}

return ans;

}

};

复杂度分析

时间复杂度:\(O(log(n))\)。对于 n 的每个二进制位,我们最多只能乘一次。所以总的时间复杂度为 \(O(log(n))\)。

空间复杂度:\(O(1)\)。我们只需要两个变量来存储 x 的当前乘积和最终结果。

位运算实现pow(x,n)

根据暴力法的思路来看特别简单,但通过位运算呢?

我举个例子吧,例如 n = 13,则 n 的二进制表示为 1101, 那么 m 的 13 次方可以拆解为:

\(m^{1101} = m^{0001} * m^{0100} * m^{1000}\)。

我们可以通过 & 1和 >>1 来逐位读取 1101,为1时将该位代表的乘数累乘到最终结果。直接看代码吧,反而容易理解:

int pow(int n){

int sum = 1;

int tmp = m;

while(n != 0){

if(n & 1 == 1){

sum *= tmp;

}

tmp *= tmp;

n = n >> 1;

}

return sum;

}

时间复杂度近为 \(O(logn)\),而且看起来很牛逼

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值