Recursion vs Iteration
Most problems that can be solved with recursion can also be solved with a loop (iteration), and the other way round. So which should you write? Both are correct tools; they differ in readability, speed and memory. Seeing the same problems solved both ways is the quickest way to learn when each one fits.
Factorial Both Ways
public class FactLoop {
static long factorial(int n) {
long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
public static void main(String[] args) {
System.out.println(factorial(10));
}
}public class FactRec {
static long factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
System.out.println(factorial(10));
}
}3628800Both print 3,628,800. The loop uses one variable; the recursive version uses one stack frame per call (10 here).
Fibonacci: Where Naive Recursion Hurts
public class Fib {
static long calls = 0;
static long fibRec(int n) {
calls++;
if (n < 2) {
return n;
}
return fibRec(n - 1) + fibRec(n - 2);
}
static long fibLoop(int n) {
long a = 0, b = 1;
for (int i = 0; i < n; i++) {
long next = a + b;
a = b;
b = next;
}
return a;
}
public static void main(String[] args) {
System.out.println("Loop: " + fibLoop(30));
long result = fibRec(30);
System.out.println("Recursive: " + result + " using "
+ calls + " calls");
}
}Loop: 832040
Recursive: 832040 using 2692537 callsHow it works
fibRec(30)callsfibRec(29)andfibRec(28), andfibRec(29)callsfibRec(28)again, and so on. The same values are recomputed again and again: almost 2.7 million calls.fibLoop(30)computes each value once: 30 rounds.- Each extra
nroughly multiplies the recursive work by 1.6, sofibRec(50)would take billions of calls.
Try it yourself: print the number of calls for fibRec(20) and fibRec(25). How fast does it grow?
Side by Side
| Iteration (loop) | Recursion | |
|---|---|---|
| Memory | Constant: a few variables | One stack frame per active call |
| Risk | Infinite loop | StackOverflowError when too deep |
| Speed | Usually a little faster | A little overhead per call; can repeat work |
| Readability | Best for simple counting and sequences | Best for problems that split into smaller copies |
| Natural fit | Totals, counting, walking arrays | Trees, folders inside folders, divide and conquer |
Common Mistakes
Using naive recursion for Fibonacci in real code. Use a loop, or recursion with memoization.
Turning every loop into recursion. For simple counting, it only adds stack frames and risk.
Forgetting stack limits. Recursion 100,000 levels deep can overflow even when the logic is correct. Java doesn't optimize tail calls, so deep chains are safer as loops.
Interview Corner
What is the difference between recursion and iteration?
Iteration repeats with a loop and uses constant memory. Recursion repeats by a method calling itself; each call uses a stack frame, so deep recursion can cause StackOverflowError. Recursion often reads more naturally for problems that break into smaller copies, while loops are usually faster and safer for long, simple repetition.
Why is the naive recursive Fibonacci slow?
Each call makes two more calls, so the same Fibonacci numbers are computed again and again; the number of calls grows exponentially with n. An iterative version, or recursion with memoization, computes each value once.
Practice
- Easy: Write
sumTo(n)both iteratively and recursively, and check they agree for n = 100. - Harder: Add a
long[] memoarray tofibRecso each value is computed only once, and count the calls for n = 30 again.
Key Takeaways
Was this tutorial helpful?