LeetCode - Pow(x, n)
Problem description
Implement pow(x, n), which calculates x raised to the power n (xn).
Example 1:
1
2
Input: 2.00000, 10
Output: 1024.00000
Example 2:
1
2
Input: 2.10000, 3
Output: 9.26100
Example 3:
1
2
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]
Analysis
Just use doubling every time to reduce calculation. But the edge case is annoying.
Some edge case: (1, Integer.MAX_VALUE) (-1, Integer.MIN_VALUE) (-3, 7)
Here’s the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class MyPow {
public double myPow(double x, int n) {
if (n == 0) {
return 1;
}
if (x == 0) {
return 0;
}
int flag = n % 2 == 0 ? 1 : x < 0 ? -1 : 1;
int absN = Math.abs(n);
boolean isOverflow = false;
boolean isNegative = n < 0;
if (n == Integer.MIN_VALUE) {
absN = Integer.MAX_VALUE;
isOverflow = true;
}
double res = 1;
int pow = 0;
int p = 1;
double cur = x;
while (pow + p < absN || p != 1) {
while (p + p > 0 && p + p <= absN - pow) {
cur = cur * cur;
p += p;
pow += p;
res = res * cur;
}
p = p / 2;
cur = Math.sqrt(cur);
}
if (pow + p == absN) {
res = res * cur;
}
if (isOverflow) {
res = res * Math.abs(x);
}
return flag * (isNegative ? 1 / res : res);
}
}
Note that we are not restricted to use int to store the n, so we can use long to store the n so that avoid the overflow.
Here’s the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public double myPow(double x, int n) {
if (n == 0 || x == 1)
return 1;
long N = n;
if (N < 0) {
x = 1/x;
N = -N;
}
double ans = fastPow(x, n);
return ans;
}
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 * x;
}
else {
return half * half;
}
}
What to improve
- read the description carefully.