c语言函数 fast pow2,Pow(x, n)【多解法】

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.00000, 10

输出: 1024.00000

示例 2:

输入: 2.10000, 3

输出: 9.26100

示例 3:

输入: 2.00000, -2

输出: 0.25000

解释: 2-2 = 1/22 = 1/4 = 0.25

说明:

-100.0 < x < 100.0

n 是 32 位有符号整数,其数值范围是 [−231, 231− 1] 。

方法一:暴力法

思路

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

如果 n<0,我们可以直接用 ,−n 来替换 x,n 以保证 n≥0。该限制可以简化我们的进一步讨论。

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

算法

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

class Solution {

public double myPow(double x, int n) {

long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

double ans = 1;

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

ans = ans * x;

return ans;

}

};

复杂度分析

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

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

方法二:递归快速幂算法

思路

假设我们已经得到了的结果,那么如何才能算出 ?显然,我们不需要再乘上 n 个 x。 使用公式 ,只需要一次计算,我们就可以得到 。这种优化可以降低算法的时间复杂度。

算法

假设我们已经得到了 的结果,现在想要计算 的结果。 设 A 是 的结果,我们可以分别根据 n 的奇偶来讨论 。

如果 n 是偶数,我们可以使用公式 得到

如果 n 是奇数,那么 。

直观地说,我们需要将另一个 x 和结果相乘,所以 。 这种方法可以很容易地用递归实现。 我们称这个方法为“快速幂(Fast Power)”,因为我们最多只需要 次计算就可以得到 。

class Solution {

private double fastPow(double x, 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;

}

}

public double myPow(double x, int n) {

long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

return fastPow(x, N);

}

};

复杂度分析

时间复杂度:。每次我们应用公式 ,n 就减少一半。 因此,我们最多需要 次计算来得到结果。

空间复杂度:。每次计算,我们都需要存储 的结果。 我们需要计算 次,因此空间复杂度为 。

方法三:迭代快速幂算法

思路

使用公式,我们可以将 n 写成一些正整数的和,。如果我们可以快速得到 的结果,那么就可以减少计算 所需的时间。

算法

我们可以利用 n 的二进制表示来更好地理解该问题。设 n 从最低有效位(LSB)到最高有效位(MSB)的二进制表示为 。对于第 i 位,如果 ,那么意味着结果需要乘以 。

看上去这种表示法似乎没有任何改进,因为 。但是使用上面提到的公式,还是可以看到一些差异。最初,对于每个 ,我们可以使用 的结果一步得到 。因为的数目最多为 ,所以我们可以在 的时间内得到所有的。在这之后,对于满足 的所有 i,我们可以用 乘以结果。这也需要 的时间。

递归或迭代的快速幂实际上是实现同一目标的不同方式。关于快速幂算法的更多信息,可以访问它的 wiki1 或百度百科2。

class Solution {

public double myPow(double x, int n) {

long N = n;

if (N < 0) {

x = 1 / x;

N = -N;

}

double ans = 1;

double current_product = x;

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

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

ans = ans * current_product;

}

current_product = current_product * current_product;

}

return ans;

}

};

复杂度分析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值