简介
Implement pow(x, n), which calculates x raised to the power n (xn).
Example 1:
Input: 2.00000, 10
Output: 1024.00000
Example 2:
Input: 2.10000, 3
Output: 9.26100Example 3:
Input: 2.00000, -2
Output: 0.25000
Explanation: 2 -2 = 1/2 2 = 1/4 = 0.25Note:
- -100.0 < x < 100.0
- n is a 32-bit signed integer, within the range [−231, 231 − 1]
解题思路
这道题看到的时候最直接的想法就是用循环累乘,但是这样会超时。。。。
所以要想一个优化的算法来求解;
采用折半法,将n除以2,然后递归,最后n的值肯定为0,这时候再往回乘
判断n的基偶,若为偶,返回上次递归后得到的平方;
若为基,返回上次递归后得到的平方,再乘上x的值;
需要注意的是:
- 若n为负数,则需要将n取反,x取为其倒数;
- 考虑边界问题,-2147483648 <= n <= 2147483647,此时若n = -2147483648,取反后为2147483648,大于2147483647,会越界
解决办法:令 n’ = n+1 = -2147483647 ,求xn等价于求 xn’ * x-1
参考代码
方法一:采用辅助函数来进行递归
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
double myPow(double x, int n) {
if(n == 0)return 1;
if(n > 0)
{
return Pow(x, n);
}
else
{
return 1/x * Pow(1/x, -(n+1));//少乘了一个
}
}
private:
double Pow(double x, int n)
{
if(n == 0)return 1;
double half = Pow(x, n >> 1);//右移,相当于除以2
if((n&1) == 0)//判断基偶,相当于 n%2 == 0
{
return half * half;
}
else
{
return x * half * half;
}
}
};
方法二:直接递归
class Solution {
public:
double myPow(double x, int n) {
if (n < 0)
return 1 / x * myPow(1 / x, -(n + 1));
else if (n == 0)
return 1;
else if (n == 1) //这个条件写不写都没关系,写了话返回更早一步
return x;
double half = myPow(x, n >> 1);
half *= half;
if ((n & 1) == 1)
half *= x;
return half;
}
};
参考:
LeetCode 50_Pow(x, n) 乘方实现
LeetCode Pow(x, n) 求x的n次方
总结
采用折半的思想可以优化程序
位运算