Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Introduction to Backtracking
Backtracking is a systematic technique for solving computational problems by exploring all possible solutions incrementally and abandoning paths that cannot lead to a valid solution. It uses recursive calling to build solutions step by step, removing invalid solutions based on problem constraints.
Types of Backtracking Problems
Backtracking algorithm is applied to three main types of problems −
- Decision problems − Find any feasible solution
- Optimization problems − Find the best solution among all feasible solutions
- Enumeration problems − Find all feasible solutions to the problem
How Backtracking Works
The algorithm explores solution paths by making choices at each step. When it reaches a dead end or invalid state, it backtracks to the previous decision point and tries alternative choices.
General Algorithm
if (current_position is goal)
return success
else if (current_position is invalid)
return failure
else
for each possible next_move from current_position
make next_move
if (solve(next_position) == success)
return success
undo next_move (backtrack)
return failure
Example 1: N-Queens Problem
Place N queens on an N×N chessboard such that no two queens attack each other. Here's a solution for the 4-Queens problem −
#include <stdio.h>
#include <stdbool.h>
#define N 4
void printSolution(int board[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d ", board[i][j]);
}
printf("<br>");
}
}
bool isSafe(int board[N][N], int row, int col) {
// Check column
for (int i = 0; i < row; i++)
if (board[i][col] == 1) return false;
// Check diagonal
for (int i = row-1, j = col-1; i >= 0 && j >= 0; i--, j--)
if (board[i][j] == 1) return false;
for (int i = row-1, j = col+1; i >= 0 && j < N; i--, j++)
if (board[i][j] == 1) return false;
return true;
}
bool solveNQueens(int board[N][N], int row) {
if (row >= N) return true;
for (int col = 0; col < N; col++) {
if (isSafe(board, row, col)) {
board[row][col] = 1;
if (solveNQueens(board, row + 1))
return true;
board[row][col] = 0; /* Backtrack */
}
}
return false;
}
int main() {
int board[N][N] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};
if (solveNQueens(board, 0)) {
printf("Solution exists:<br>");
printSolution(board);
} else {
printf("No solution exists<br>");
}
return 0;
}
Solution exists: 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0
Example 2: Rat in a Maze
Find a path from top-left corner to bottom-right corner in a maze where 1 represents open path and 0 represents blocked path −
#include <stdio.h>
#include <stdbool.h>
#define N 4
void printSolution(int solution[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d ", solution[i][j]);
}
printf("<br>");
}
}
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 solution[N][N]) {
if (x == N-1 && y == N-1) {
solution[x][y] = 1;
return true;
}
if (isSafe(maze, x, y)) {
solution[x][y] = 1;
/* Move right */
if (solveMaze(maze, x, y+1, solution))
return true;
/* Move down */
if (solveMaze(maze, x+1, y, solution))
return true;
solution[x][y] = 0; /* Backtrack */
return false;
}
return false;
}
int main() {
int maze[N][N] = {{1, 1, 0, 0},
{1, 1, 1, 0},
{0, 1, 1, 1},
{0, 0, 1, 1}};
int solution[N][N] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};
if (solveMaze(maze, 0, 0, solution)) {
printf("Path found:<br>");
printSolution(solution);
} else {
printf("No path exists<br>");
}
return 0;
}
Path found: 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1
Key Characteristics
- State space tree − Explores all possible solution paths systematically
- Pruning − Eliminates branches that cannot lead to valid solutions
- Recursive nature − Uses recursion to explore solution space
- Memory efficiency − Uses constant extra space (excluding recursion stack)
Conclusion
Backtracking is a powerful technique for solving constraint satisfaction problems by systematically exploring all possibilities. It's particularly effective for problems like N-Queens, Sudoku, and maze solving where we need to find valid arrangements or paths.
