LeetCode - Pow(x, n)

2 minute read

Problem description

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.