Fast Exponentiation Power in Log N in DSA C - Time & Space Complexity
We want to know how fast the fast exponentiation method calculates powers compared to simple repeated multiplication.
How does the number of steps grow when the power gets bigger?
Analyze the time complexity of the following code snippet.
int fastPower(int base, int exp) {
if (exp == 0) return 1;
int half = fastPower(base, exp / 2);
if (exp % 2 == 0) return half * half;
else return base * half * half;
}
This code calculates base raised to the power exp using a method that splits the problem in half each time.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls that halve the exponent each time.
- How many times: About log base 2 of exp times, because the exponent is divided by 2 each call.
Each time we call the function, the exponent gets cut in half, so the number of calls grows slowly as the exponent grows.
| Input Size (exp) | Approx. Operations (recursive calls) |
|---|---|
| 10 | About 4 |
| 100 | About 7 |
| 1000 | About 10 |
Pattern observation: Doubling the exponent adds only one more step, so growth is very slow.
Time Complexity: O(log n)
This means the number of steps grows slowly, only a little more work for much bigger powers.
[X] Wrong: "The function does one multiplication per power, so it must be O(n)."
[OK] Correct: The function splits the problem in half each time, so it does far fewer steps than multiplying n times.
Understanding this method shows you can improve simple tasks by clever thinking, a skill valued in real coding challenges.
"What if we changed the code to use a loop instead of recursion? How would the time complexity change?"
Practice
Fast Exponentiation Power in Log N over the simple repeated multiplication method?Solution
Step 1: Understand simple exponentiation time
Simple repeated multiplication multiplies the base n times, so it takes O(n) time.Step 2: Understand fast exponentiation time
Fast exponentiation uses squaring and divides the problem size by 2 each step, so it takes O(log n) time.Final Answer:
It reduces the time complexity from O(n) to O(log n) -> Option AQuick Check:
Fast exponentiation = O(log n) [OK]
- Thinking it avoids multiplication
- Confusing time complexity with memory usage
- Assuming it only works for positive exponents
pow(base, exponent) using fast exponentiation recursively?Solution
Step 1: Identify recursive fast exponentiation
int fastPow(int base, int exp) { if (exp == 0) return 1; int half = fastPow(base, exp / 2); if (exp % 2 == 0) return half * half; else return base * half * half; } uses recursion, divides exponent by 2, and squares the half result, matching fast exponentiation logic.Step 2: Check other options
int fastPow(int base, int exp) { int result = 1; for (int i = 0; i < exp; i++) result *= base; return result; } is simple loop (not fast). int fastPow(int base, int exp) { if (exp == 1) return base; return base * fastPow(base, exp - 1); } is simple recursion without divide and conquer. int fastPow(int base, int exp) { return base ^ exp; } uses bitwise XOR, not power.Final Answer:
int fastPow(int base, int exp) { if (exp == 0) return 1; int half = fastPow(base, exp / 2); if (exp % 2 == 0) return half * half; else return base * half * half; } -> Option AQuick Check:
Recursive fast exponentiation = int fastPow(int base, int exp) { if (exp == 0) return 1; int half = fastPow(base, exp / 2); if (exp % 2 == 0) return half * half; else return base * half * half; } [OK]
- Using simple loops instead of divide and conquer
- Confusing bitwise XOR (^) with power
- Missing base case for exponent 0
int fastPow(int base, int exp) {
if (exp == 0) return 1;
int half = fastPow(base, exp / 2);
if (exp % 2 == 0) return half * half;
else return base * half * half;
}
int main() {
printf("%d", fastPow(2, 5));
return 0;
}Solution
Step 1: Trace fastPow(2, 5)
fastPow(2,5) calls fastPow(2,2), which calls fastPow(2,1), which calls fastPow(2,0)=1. Then compute up: fastPow(2,1)=2*1*1=2, fastPow(2,2)=2*2=4, fastPow(2,5)=2*4*4=32.Step 2: Confirm output
The final printed value is 32.Final Answer:
32 -> Option BQuick Check:
2^5 = 32 [OK]
- Confusing multiplication order
- Forgetting base case returns 1
- Miscomputing odd exponent step
int fastPow(int base, int exp) {
if (exp == 0) return 1;
int half = fastPow(base, exp / 2);
if (exp % 2 == 0) return half * half;
else return base * half;
}Solution
Step 1: Analyze odd exponent case
For odd exponent, result should be base * half * half, but code returns base * half only, missing one multiplication.Step 2: Fix the return statement
Change last line to return base * half * half to correctly compute power for odd exponents.Final Answer:
Change last line to return base * half * half; -> Option CQuick Check:
Odd exponent step needs base * half * half [OK]
- Returning base * half instead of base * half * half
- Changing base case incorrectly
- Replacing exp / 2 with exp - 1
pow(base, exponent) modulo m efficiently using fast exponentiation. Which modification should you apply to the standard fast exponentiation algorithm to handle large numbers without overflow?Solution
Step 1: Understand overflow risk
Multiplying large numbers can overflow integer limits before modulo is applied.Step 2: Apply modulo after each multiplication
To avoid overflow and keep numbers small, apply modulo after every multiplication step in fast exponentiation.Final Answer:
Apply modulo operation after each multiplication step -> Option DQuick Check:
Modulo after each multiply prevents overflow [OK]
- Applying modulo only once at the end
- Using floating point causing precision errors
- Relying on bigger integer types without modulo
Ready to prove it?
Pass the test and this pattern moves unknown
