【LeetCode & 剑指offer刷题】分治法题1:16 数值的整数次方(50. Pow(x, n))
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
50. Pow(x, n)
Example 1:
Input: 2.00000, 10
Output: 1024.00000
Example 2:
Input: 2.10000, 3
Output: 9.26100
Example 3:
Input: 2.00000, -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25
Note:
-
-100.0 < x < 100.0
-
n is a 32-bit signed integer, within the range [−231, 231 − 1]
//问题:实现求x^n
//递归法 掌握
x^n = x^(n/2) * x^(n/2) ,n为偶数
= x^(n/2) * x^(n/2) * x, n为奇数时(假设这里的n/2已向下取整)
例子:
pow(x,10) -> pow(x,5) -> pow(x,2) -> ...
/*
分治法
O(logn)
*/
class Solution
{
public:
double myPow(double x, int n)
{
if (n < 0) return 1.0 / power(x, -n); //负次幂的处理
else return power(x, n);
}
private:
double power(double x, int n)
{
if (n == 0) return 1;
double res = power(x, n / 2); //分解,n/2为隐式向下取整
if (n % 2 == 0)
return res * res; //偶数时
else
return res * res * x; //奇数时
}
};
//迭代法
class Solution
{
public:
double myPow(double x, int n)
{
if(n == 0) return 1;
unsigned int p;
if(n<0)//负数时
{
p=-n; //这里需用比n范围大的数存储,因为如果用n存在问题:n = -2147483648时会溢出
x = 1/x;
}
else p = n;
double ans = 1;
while(p>0)
{
if(p%2 == 1) ans *= x; //p为奇数时执行此句子
x*=x;
p /= 2;
}
return ans;
}
};
/*
过程举例:
p
10:x = xprev^2 n = 5
5:ans = xprev^2; x = xprev^4 n = 2
2:x = xprev^8 n = 1
1:ans = xprev^2 * xprev^8 n = 0 退出循环
10转为二进制为1010,10 = 8 + 2,x^2*x^8即可,二进制中为1的地方就是p除以2为奇数的地方
2L10 0
2L5 1
2L2 0
1
*/