题目相关
题目链接
LeetCode中国,https://leetcode-cn.com/problems/powx-n/。
题目描述
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
说明:
- -100.0 < x < 100.0
- n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。
示例
示例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
题目分析
LeetCode 给出本题难度中等。按照 LeetCode 给出的算法标签为二分查找。我看到这个题目就满脸懵逼了,怎么二分查找。我们知道对于二分查找而言,我们需要确认以下几个部分:
1、查找左边界,left。
2、查找右边界,right。
3、check 函数。
这题怎么看最快的方法就是快速幂啊。和二分查找好像没什么关系吧。在脑子里回顾了一下快速幂的基本思路:
1、用递归来实现,每次递归的时候将指数除 2。
2、如果是偶数,则指数乘自己。
3、如果是奇数,则自己乘自己再乘 x。
哦,确实快速幂属于二分的范畴,这个好像真的命中了我的一个知识盲区。
样例数据分析
比较简单,就不仔细分析了。要注意的事情是,如果指数为负数,幂运算是如何进行的。
算法设计
暴力
就是直接计算 n 次,就可以得到答案,这样的算法复杂度为 O(n)。当然,本题如果使用暴力算法,结果必然是 TLE。
快速幂
使用二分的方法,可以将暴力算法复杂度降低为 O(logn)。
AC 参考代码
class Solution {
public:
//递归+快速幂
double fastPow(double x, long long n) {
//出口条件
if (0==n) {
return 1.0;
}
//数据处理
double ans = fastPow(x, n/2);
//形成递归
if (0==n%2) {
//偶数
return ans*ans;
} else {
//奇数
return ans*ans*x;
}
}
double myPow(double x, int n) {
long long t = n;
if (n<0) {
//
x = 1/x;
t = -1*t;
}
return fastPow(x, t);
}
};
代码细节
上面有一个小细节,就是当指数为负数的时候,我们直接将 n=-1*n,会导致数据越界错误。当 n=-2147483648 的时候,-1*n=2147483648,这个数据超过了 int 可以表示的范围。在 LeetCode 中,会导致一个异常。异常表示如下:
所以我们需要一个临时变量 long long 类型,来解决这个问题。