Recursion and Backtracking form the foundation of advanced problem solving.
This module trains the mind to break problems into smaller decisions, explore multiple possibilities, and systematically build correct solutions.
Most learners fear recursion not because it is difficult, but because they don’t visualize it correctly. This module fixes that gap.
A recursion tree visually represents how recursive calls branch and execute.
Each node represents:
The call stack stores:
Each recursive call occupies a new stack frame.
int fact(int n){
if(n == 0) return 1;
return n * fact(n - 1);
}
Call sequence:
Stack grows until base case, then unwinds.
Understanding recursion is about visualizing stack growth and collapse, not memorizing code.
A recursive function is tail recursive if the recursive call is the last operation.
Example:
int factTail(int n, int result){
if(n == 0) return result;
return factTail(n - 1, n * result);
}
Java does not optimize tail recursion automatically, but understanding it improves logic clarity.
The result is passed through parameters.
Example:
void sum(int i, int total){
if(i == 0){
System.out.println(total);
return;
}
sum(i - 1, total + i);
}
The function returns the result.
Example:
int sum(int n){
if(n == 0) return 0;
return n + sum(n - 1);
}
Example comparison:
Recursive:
int fib(int n){
if(n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
Iterative:
int a = 0, b = 1;
for(int i = 2; i <= n; i++){
int c = a + b;
a = b;
b = c;
}
Understand recursion deeply, but optimize with iteration when required.
Backtracking is a technique where:
It is recursion with decision-making.
void solve(state){
if(baseCondition) return;
for(choice : allChoices){
makeChoice;
solve(updatedState);
undoChoice;
}
}
Used in:
All possible selections of elements (order doesn’t matter).
Example:
void subsets(int index, List<Integer> current){
if(index == n){
print(current);
return;
}
current.add(arr[index]);
subsets(index + 1, current);
current.remove(current.size() - 1);
subsets(index + 1, current);
}
Total subsets: 2ⁿ
Same as subsets but often discussed in sequence context.
Key idea: pick or not pick
Order matters.
Example:
void permute(int index){
if(index == n){
print(arr);
return;
}
for(int i = index; i < n; i++){
swap(index, i);
permute(index + 1);
swap(index, i);
}
}
Time Complexity: O(n!)
Order does not matter.
Example idea:
Used in:
Place N queens on an N×N chessboard such that:
Core logic:
if(isSafe(row, col)){
board[row][col] = 'Q';
solve(row + 1);
board[row][col] = '.';
}
This problem teaches:
Fill a 9×9 board so that:
This problem simulates real-world constraint solving.
Given a grid with blocked and open cells, find a path from source to destination.
Key learning:
Given a grid of characters and a word, check if the word exists in the grid.
Rules:
Used heavily in interviews and online judges.