Fast Exponentiation Power in Log N in DSA Go - Time & Space Complexity
We want to understand how fast the power calculation grows as the exponent gets bigger.
How does the number of steps change when we calculate x to the power n?
Analyze the time complexity of the following code snippet.
func fastPower(x int, n int) int {
if n == 0 {
return 1
}
half := fastPower(x, n / 2)
if n % 2 == 0 {
return half * half
} else {
return half * half * x
}
}
This code calculates x raised to the power n using a fast method by splitting the problem in half each time.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls that halve the exponent n each time.
- How many times: About log base 2 of n times, because n is divided by 2 each step.
Each time we call the function, the exponent gets cut in half, so the number of steps grows slowly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 recursive calls |
| 100 | About 7 recursive calls |
| 1000 | About 10 recursive calls |
Pattern observation: Doubling n adds only one more step, so growth is very slow.
Time Complexity: O(log n)
This means the steps needed grow slowly as the exponent gets bigger, making it very efficient.
[X] Wrong: "Calculating power always takes n steps because we multiply x n times."
[OK] Correct: This method uses splitting to reduce steps to about log n, not n, so it is much faster.
Knowing how to speed up power calculations shows you understand how to reduce repeated work, a key skill in many problems.
"What if we changed the code to use a loop instead of recursion? How would the time complexity change?"
Practice
Solution
Step 1: Understand simple exponentiation
Simple method multiplies the base by itself n times, so it takes n multiplications.Step 2: Understand fast exponentiation
Fast exponentiation uses repeated squaring, reducing multiplications to about log n times.Final Answer:
It reduces the number of multiplications from n to log n -> Option AQuick Check:
Fast exponentiation = fewer multiplications [OK]
- Thinking it only works for even powers
- Confusing memory use with speed
- Believing it avoids multiplication
Solution
Step 1: Identify parameter types for integer power
Base and exponent should be integers for integer power calculation.Step 2: Check return type
Return type should be int to match integer power result.Final Answer:
func fastPower(base int, exp int) int -> Option CQuick Check:
Integer base and exponent with int return [OK]
- Using float64 for exponent when integer is needed
- Returning float64 instead of int
- Mixing base and exponent types
func fastPower(base int, exp int) int {
if exp == 0 {
return 1
}
half := fastPower(base, exp/2)
if exp%2 == 0 {
return half * half
} else {
return half * half * base
}
}
fmt.Println(fastPower(2, 5))Solution
Step 1: Trace recursive calls for fastPower(2, 5)
fastPower(2,5) calls fastPower(2,2), which calls fastPower(2,1), which calls fastPower(2,0)=1.Step 2: Calculate results bottom-up
fastPower(2,1) = 1*1*2=2; fastPower(2,2) = 2*2=4; fastPower(2,5) = 4*4*2=32.Final Answer:
32 -> Option BQuick Check:
2^5 = 32 [OK]
- Confusing multiplication order
- Forgetting to multiply by base for odd exponent
- Miscomputing base cases
func fastPower(base int, exp int) int {
if exp == 0 {
return 0
}
half := fastPower(base, exp/2)
if exp%2 == 0 {
return half * half
} else {
return half * half * base
}
}Solution
Step 1: Check base case for exponent 0
Exponent 0 means power is 1, but code returns 0, which is incorrect.Step 2: Verify other parts
Multiplication and division logic is correct; negative exponent handling is not required here.Final Answer:
Base case returns 0 instead of 1 -> Option DQuick Check:
Power of 0 exponent = 1 [OK]
- Returning 0 for exp=0 base case
- Ignoring negative exponent cases
- Misplacing multiplication logic
Solution
Step 1: Understand modular exponentiation
To avoid overflow and keep numbers small, apply modulo after each multiplication.Step 2: Modify fastPower to include modulo
Insert modulo operation after multiplying halves and base to keep intermediate results within mod.Final Answer:
Add modulo operation after each multiplication to keep numbers small -> Option AQuick Check:
Modulo after multiplication prevents overflow [OK]
- Delaying modulo until end causes overflow
- Using float64 instead of int causes precision loss
- Multiplying base by mod increases value incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
