Pow(x, n)

Medium Math

Problem

Given a floating-point number x and an integer n, return x raised to the power n (i.e., x^n).

  • −100.0 < x < 100.0
  • −2³¹ ≤ n ≤ 2³¹ - 1

Example

Input: x = 2.0, n = 10
Output: 1024.0

A naive approach would multiply 2.0 by itself 10 times, resulting in 1024.0. However, this requires 10 multiplications. The recursive divide and conquer approach reduces the number of multiplications by repeatedly squaring the base and halving the exponent. For example, 2^10 = (2^5)^2. The recursion continues until the exponent reaches zero (base case), returning 1. The critical moment is when the exponent is odd, requiring an extra multiplication by the base to account for the leftover factor.

Approach

Straightforward Solution

A straightforward solution multiplies x by itself n times, resulting in O(n) time complexity, which is inefficient for large n.

Core Observation

Exponentiation can be expressed recursively as x^n = (x^2)^(n//2) when n is even, and x * (x^2)^(n//2) when n is odd. This reduces the problem size by half at each step, enabling logarithmic time complexity.

Path to Optimal

Recognizing that repeated multiplication can be optimized by squaring the base and halving the exponent leads to a divide and conquer approach. This reduces the number of multiplications from linear to logarithmic in n. Handling negative exponents requires computing the reciprocal of the positive exponent result.

Optimal Approach

Implement a recursive helper function that returns 1 if n is zero, returns 0 if x is zero, and otherwise recursively computes helper(x*x, n//2). If n is odd, multiply the result by x. The main function calls this helper with the absolute value of n and returns the result or its reciprocal depending on the sign of n.

Time

O(log n)

Each recursive call halves the exponent n, leading to a recursion depth of log n. Each call performs a constant number of multiplications.

Space

O(log n)

The recursion stack depth is proportional to log n due to halving the exponent at each step. No additional significant auxiliary space is used.

Pattern Spotlight

Divide and Conquer (Exponentiation by Squaring)

To compute powers efficiently, recursively reduce the exponent by half each step by squaring the base, and multiply by the base once more if the exponent is odd; this transforms O(n) multiplications into O(log n).

Solution

1class Solution:
2 def myPow(self, x: float, n: int) -> float:
3 def helper(x, n):
4 if x == 0: return 0
5 if n == 0: return 1
6
7 res = helper(x * x, n // 2)
8 return x * res if n % 2 else res
9
10 res = helper(x, abs(n))
11 return res if n >= 0 else 1 / res

Step-by-Step Solution

1

Handle Negative and Zero Exponents with Recursive Helper

4if x == 0: return 0
5if n == 0: return 1
7res = helper(x * x, n // 2)

Objective

To correctly compute power for positive exponents and handle zero and zero-base edge cases.

Key Insight

The recursive helper function uses divide and conquer by squaring the base and halving the exponent, which reduces the problem size exponentially. It returns 1 when the exponent is zero, as any number to the zero power is 1, and returns 0 immediately if the base is zero, as zero to any positive power is zero. This base case handling prevents unnecessary recursion and ensures correctness.

Interview Quick-Check

Core Logic

The helper function recursively computes power by squaring the base and halving the exponent, returning 1 for exponent zero and 0 for base zero.

State & Boundaries

Base cases prevent infinite recursion and handle mathematical edge cases: x == 0 returns 0, n == 0 returns 1.

Common Pitfalls & Bugs

Failing to handle zero base or zero exponent correctly can lead to incorrect results or infinite recursion.

2

Combine Recursive Results and Handle Odd Exponents

8return x * res if n % 2 else res

Objective

To combine the recursive results by multiplying the squared base power and adjusting for odd exponents.

Key Insight

After recursively computing helper(x*x, n//2), the algorithm checks if n is odd. If so, it multiplies the result by x to account for the extra factor lost during integer division of n by 2. This step ensures the correctness of the exponentiation for odd powers while maintaining logarithmic complexity.

Interview Quick-Check

Core Logic

Multiplying by x when n is odd corrects for the truncated exponent in the recursive call, preserving the exact power.

Common Pitfalls & Bugs

Omitting the multiplication for odd exponents leads to incorrect results, especially for odd powers.

3

Adjust Final Result for Negative Exponents

10res = helper(x, abs(n))
11return res if n >= 0 else 1 / res

Objective

To compute the final power value by handling negative exponents via reciprocal.

Key Insight

Since the helper function only computes powers for non-negative exponents, the main function calls it with the absolute value of n. If n is negative, the final result is the reciprocal of the helper's output, implementing the mathematical rule x^-n = 1 / x^n. This separation simplifies the recursive logic and ensures correctness for all integer exponents.

Interview Quick-Check

Core Logic

Using the reciprocal for negative exponents correctly implements the mathematical definition of negative powers.

Common Pitfalls & Bugs

Failing to handle negative exponents leads to incorrect results or infinite recursion.

Line Analysis

This solution has 4 Critical lines interviewers watch for.

Line 5 Critical
if n == 0: return 1

Return 1 if the exponent n is zero.

Any number raised to the zero power is 1, making this the essential base case for terminating recursion.

Line 8 Critical
return x * res if n % 2 else res

Multiply by x if n is odd, otherwise return the recursive result directly.

Multiplying by x when n is odd accounts for the lost factor due to integer division, ensuring the correctness of the exponentiation.

Line 7 Critical
res = helper(x * x, n // 2)

Recursively compute helper(x squared, n halved).

This line implements the divide and conquer step by reducing the problem size exponentially, enabling O(log n) time complexity.

Line 11 Critical
return res if n >= 0 else 1 / res

Return the result or its reciprocal depending on the sign of n.

This line implements the mathematical rule for negative exponents by returning the reciprocal of the positive power, ensuring correctness for all integer exponents.

Line 4 Core
if x == 0: return 0

Return 0 immediately if the base x is zero.

Zero raised to any positive power is zero, so returning 0 here prevents unnecessary recursion and correctly handles this edge case.

Line 10 Core
res = helper(x, abs(n))

Call the helper function with the absolute value of n.

This isolates the recursive logic to positive exponents, simplifying the implementation and avoiding negative exponent complications within recursion.

Test Your Understanding

Why does the algorithm multiply by x only when the exponent n is odd?

Because when n is odd, dividing it by 2 truncates the exponent, losing one factor of x. Multiplying by x once more accounts for this leftover factor, ensuring the correctness of the exponentiation.

Related Problems

Math pattern

Don't just read it. Drill it.

Reconstruct Pow(x, n) from memory until it sticks. AlgoDrill blanks out key lines and makes you fill them back in, step by step.

Unlock the Pow(x, n) drill

or drill a free problem