Topics › Recursion and Backtracking › Get a Strong Hold
Pow(x, n)
LeetCode ↗ Java source ↗ Edit this article ↗
Jump to code:
Problem
Given a real number x and an integer n, compute x^n (x raised to the power n). The exponent may be negative, in which case x^n = 1 / x^(-n).
Constraints: -100.0 < x < 100.0, -2^31 ≤ n ≤ 2^31 - 1, and either x is non-zero or n is positive. The answer fits in a double.
Example 1
x = 2.0, n = 10
answer = 1024.0 // 2 multiplied by itself 10 times
Example 2
x = 2.0, n = -2
answer = 0.25 // 1 / 2^2
Example 3
x = 2.1, n = 3
answer = 9.261 // 2.1 * 2.1 * 2.1
The interesting part is the size of n. Two billion multiplications is too slow, so the task is really “compute a power in far fewer than n steps”, and the recursion that does it is one of the most reused ideas in the sheet (modular exponentiation, matrix powers, fast Fibonacci).
Approach 1: Brute force
Intuition. x^n is x multiplied by itself n times, so do exactly that. For a negative exponent compute the positive power and take its reciprocal.
Algorithm.
- Let
times = |n|, computed in along. - Multiply
result(initially1.0) byx,timestimes. - If
n < 0return1 / result, otherwiseresult.
static double bruteForce(double x, int n) {
long times = Math.abs((long) n); // cast first: Math.abs(Integer.MIN_VALUE) is still negative
double result = 1.0;
for (long i = 0; i < times; i++) result *= x;
return n < 0 ? 1.0 / result : result;
}
Complexity. Time O(|n|). Space O(1).
The cast to long before Math.abs is not cosmetic. Integer.MIN_VALUE is -2^31, and +2^31 does not exist as an int, so Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE itself, a negative number, and the loop would run zero times and return 1.0 for every base. Widening first makes the absolute value correct.
With n up to 2^31 - 1 this loop takes seconds, so it is only a reference implementation.
Approach 2: Optimal, recursive fast exponentiation
Intuition. Squaring is the shortcut. x^10 = (x^5)^2, and x^5 = (x^2)^2 · x. Each step halves the exponent, so only about log2(n) multiplications are needed instead of n. The recursion is: x^0 = 1; for n > 0, compute half = x^(n/2) once, then return half · half if n is even and half · half · x if n is odd. A negative exponent is handled up front by replacing x with 1/x and n with -n.
Algorithm.
- Widen
nto along e. Ife < 0, setx = 1 / xande = -e. power(x, e): ife == 0return1.- Otherwise
half = power(x, e / 2). - Return
half * half, timesxifeis odd.
static double optimalRecursive(double x, int n) {
long e = n; // widen before negating: -Integer.MIN_VALUE does not fit in an int
if (e < 0) {
x = 1.0 / x;
e = -e;
}
return power(x, e);
}
static double power(double x, long e) {
if (e == 0) return 1.0; // base case: anything to the power 0 is 1
double half = power(x, e / 2); // one subproblem of half the size
return e % 2 == 0 ? half * half : half * half * x;
}
Dry run for x = 2, n = 10:
| call | e even? | half | returns |
|---|---|---|---|
power(2, 0) |
1 | ||
power(2, 1) |
odd | 1 | 1 · 1 · 2 = 2 |
power(2, 2) |
even | 2 | 2 · 2 = 4 |
power(2, 5) |
odd | 4 | 4 · 4 · 2 = 32 |
power(2, 10) |
even | 32 | 32 · 32 = 1024 |
Complexity. Time O(log n): the exponent halves at every level, so there are about 31 levels for the largest int. Space O(log n) for the call stack.
Two details decide whether this is actually logarithmic:
- Compute
halfonce. Writingpower(x, e / 2) * power(x, e / 2)is also correct, but it calls itself twice per level, which gives2^(log n) = nleaves and brings the running time right back toO(n). Storing the result in a local variable is the entire optimisation. - Widen before negating.
-nforn = Integer.MIN_VALUEoverflows back toInteger.MIN_VALUE. Converting tolongfirst makese = 2^31representable.
Approach 3: Optimal, iterative binary exponentiation
Intuition. Write the exponent in binary: 10 = 1010₂ = 8 + 2, so x^10 = x^8 · x^2. The powers x^1, x^2, x^4, x^8, ... are each the square of the previous one, so we can generate them in a loop and multiply into the answer exactly those whose bit is set in n. This is the same arithmetic as Approach 2 read from the other end, without recursion.
Algorithm.
- Handle a negative exponent as before.
- Keep
base = x^(2^k)andresult = 1. - While
e > 0: if the lowest bit ofeis 1,result *= base. Thenbase *= baseand shifteright by one bit. - Return
result.
static double optimalIterative(double x, int n) {
long e = n;
if (e < 0) {
x = 1.0 / x;
e = -e;
}
double result = 1.0, base = x; // after k rounds, base = x^(2^k)
while (e > 0) {
if ((e & 1) == 1) result *= base; // this bit is set: x^(2^k) belongs in the product
base *= base;
e >>= 1;
}
return result;
}
Dry run for x = 2, n = 10:
| e (binary) | lowest bit | result | base after squaring |
|---|---|---|---|
| 1010 | 0 | 1 | 4 |
| 101 | 1 | 4 | 16 |
| 10 | 0 | 4 | 256 |
| 1 | 1 | 4 · 256 = 1024 | 65536 |
Complexity. Time O(log n), one iteration per bit of the exponent. Space O(1); this is the version to use when recursion depth or stack usage matters.
Both optimal versions were tested on identical inputs, including n = Integer.MIN_VALUE, where the brute force cannot run in a reasonable time.
Edge cases and pitfalls
n = Integer.MIN_VALUE. The single most common bug. BothMath.abs(n)and-nreturn a negative number for this input. Convert tolongbefore either operation.n = 0. Every approach returns1.0, including forx = 0(the constraints exclude0^negative).- Negative base.
(-2)^31 = -2147483648and(-2)^30 = 1073741824. The sign is handled automatically because the odd factorxis multiplied in exactly once per odd level. - Underflow and overflow.
2^(-2^31)is far below the smallest positivedoubleand comes out as0.0;2^(2^31)would beInfinity. Both are the correct floating-point answers, not errors. - Floating-point comparison. The three methods multiply in different orders, so results can differ in the last bit (
2.1^3is9.261000000000001for one order). The tests compare with a relative tolerance rather than==. - Division by zero. If
x = 0andn < 0,1 / xisInfinityand the answer isInfinity; mathematically the value is undefined and the problem rules the case out. - Calling twice per level.
power(x, e/2) * power(x, e/2)silently turns theO(log n)solution intoO(n). Always store the half result.
Related problems
- Pow(x,n) is the same problem in the bit manipulation section, where the iterative version is the focus.
- Count Good Numbers needs this exact recursion with a modulus, for exponents up to
10^15. - Fibonacci Number has a fast-doubling solution built on the same halving idea.
- Check if a Number is Power of 2 or Not is the bit-level view of powers that Approach 3 relies on.