🔄 Backtracking in Data Structures & Algorithms
**Backtracking** is an algorithmic technique used for **solving recursive problems** by **exploring all possible solutions** and eliminating the ones that **fail to satisfy the constraints**. It is commonly used in **combinatorial problems, constraint satisfaction, and optimization problems**.
⚙️ How Does Backtracking Work?
Backtracking **explores possible paths recursively** and **abandons a path as soon as it determines that the path cannot lead to a valid solution**.
🔹 Steps of Backtracking Algorithm
- ✅ Choose a possible **solution candidate**.
- 🔍 Check if it **satisfies the problem constraints**.
- 🔁 If valid, **recursively explore** the next step.
- ❌ If not valid, **backtrack** (remove last choice and try another option).
🛠️ Backtracking Algorithm (Recursive Structure)
function BACKTRACKING_SOLUTION(problem, solution):
if SOLUTION_COMPLETE(solution):
return solution
for CHOICE in POSSIBLE_CHOICES:
if CHOICE_VALID(CHOICE, solution):
solution.add(CHOICE)
BACKTRACKING_SOLUTION(problem, solution)
solution.remove(CHOICE) // Backtrack if needed
📌 Types of Backtracking Problems
🔢 1. Decision Problems
Checking if a solution exists.
📊 2. Optimization Problems
Finding the **best** solution among multiple valid solutions.
🎯 3. Enumeration Problems
Finding **all possible solutions** to a problem.
🔥 Famous Backtracking Problems
🔷 1. N-Queens Problem
The **N-Queens problem** is a classic **constraint satisfaction problem** where we need to place **N queens on an N×N chessboard** such that **no two queens attack each other**.
🛠️ N-Queens Algorithm (C++)
bool isSafe(int board[][N], int row, int col) {
for (int i = 0; i < col; i++)
if (board[row][i]) return false;
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j]) return false;
for (int i = row, j = col; j >= 0 && i < N; i++, j--)
if (board[i][j]) return false;
return true;
}
bool solveNQueens(int board[][N], int col) {
if (col >= N) return true;
for (int i = 0; i < N; i++) {
if (isSafe(board, i, col)) {
board[i][col] = 1;
if (solveNQueens(board, col + 1)) return true;
board[i][col] = 0; // Backtrack
}
}
return false;
}
🧩 2. Sudoku Solver
The **Sudoku Solver** uses **backtracking** to fill missing cells while ensuring **no repetition** in rows, columns, and sub-grids.
🛠️ Sudoku Solver Algorithm (C++)
bool isValid(int board[N][N], int row, int col, int num) {
for (int x = 0; x < N; x++)
if (board[row][x] == num || board[x][col] == num) return false;
int startRow = row - row % 3, startCol = col - col % 3;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i + startRow][j + startCol] == num) return false;
return true;
}
bool solveSudoku(int board[N][N]) {
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
if (board[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValid(board, row, col, num)) {
board[row][col] = num;
if (solveSudoku(board)) return true;
board[row][col] = 0; // Backtrack
}
}
return false;
}
}
}
return true;
}
🏃♂️ 3. Rat in a Maze
The **Rat in a Maze problem** finds a **path from the start to the exit** in a **grid-based maze** using **backtracking**.
🛠️ Algorithm for Rat in a Maze (C++)
bool isSafe(int maze[N][N], int x, int y) {
return (x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1);
}
bool solveMaze(int maze[N][N], int x, int y, int sol[N][N]) {
if (x == N-1 && y == N-1) return true;
if (isSafe(maze, x, y)) {
sol[x][y] = 1;
if (solveMaze(maze, x + 1, y, sol)) return true;
if (solveMaze(maze, x, y + 1, sol)) return true;
sol[x][y] = 0; // Backtrack
}
return false;
}
⏳ Time Complexity Analysis of Backtracking
Problem | Time Complexity |
---|---|
N-Queens | O(N!) |
Sudoku Solver | O(9^(N²)) |
Rat in a Maze | O(2^(N²)) |
🌍 Real-World Applications of Backtracking
- 🔢 **AI & Machine Learning** - Constraint satisfaction.
- 📂 **Data Security** - Encryption & decryption.
- 🎮 **Game Development** - Pathfinding in **puzzle-solving games**.
- 💡 **Optimization Problems** - Scheduling & resource allocation.