Sudoku is a 9×9 grid-based puzzle where the goal is to fill each cell with digits from 1 to 9 such that:
Sudoku is a perfect example of a constraint satisfaction problem that can be solved using backtracking:
Here's how we can implement the Sudoku solver using backtracking:
O(9^(n²)), where n is the size of the Sudoku grid (typically 9). In the worst case, we need to try all 9 digits for each of the n² cells.
O(n²) for the board representation, plus O(n²) for the recursion stack in the worst case.
Learn how to solve Sudoku puzzles using backtracking.
Sudoku is a 9×9 grid-based puzzle where the goal is to fill each cell with digits from 1 to 9 such that:
Example Sudoku Puzzle:
Sudoku is a perfect candidate for backtracking because:
Each cell must satisfy row, column, and box constraints simultaneously.
We can fill the grid one cell at a time, checking constraints as we go.
We can quickly identify and abandon invalid paths without exploring all possibilities.
A properly designed Sudoku puzzle has exactly one solution, which backtracking can find.
Find an empty cell in the Sudoku grid.
Try placing digits 1-9 in the empty cell.
Check if the digit satisfies all Sudoku constraints.
If valid, recursively try to fill the rest of the grid.
If the recursive call fails, backtrack and try a different digit.
Continue until the entire grid is filled or no solution exists.
Here's how we can implement the Sudoku solver using backtracking:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182function solveSudoku(board) { // Try to solve the Sudoku puzzle solve(board); return board;} function solve(board) { // Find an empty cell const emptyCell = findEmptyCell(board); // If there are no empty cells, the puzzle is solved if (!emptyCell) { return true; } const [row, col] = emptyCell; // Try placing digits 1-9 in the empty cell for (let num = 1; num <= 9; num++) { // Check if it's valid to place the number if (isValid(board, row, col, num)) { // Place the number board[row][col] = num; // Recursively try to solve the rest of the puzzle if (solve(board)) { return true; } // If placing the number doesn't lead to a solution, backtrack board[row][col] = 0; } } // No solution found with the current configuration return false;} function findEmptyCell(board) { // Find the first empty cell (represented by 0) for (let row = 0; row < 9; row++) { for (let col = 0; col < 9; col++) { if (board[row][col] === 0) { return [row, col]; } } } // No empty cells found return null;} function isValid(board, row, col, num) { // Check if the number already exists in the row for (let x = 0; x < 9; x++) { if (board[row][x] === num) { return false; } } // Check if the number already exists in the column for (let y = 0; y < 9; y++) { if (board[y][col] === num) { return false; } } // Check if the number already exists in the 3x3 box const boxRow = Math.floor(row / 3) * 3; const boxCol = Math.floor(col / 3) * 3; for (let y = boxRow; y < boxRow + 3; y++) { for (let x = boxCol; x < boxCol + 3; x++) { if (board[y][x] === num) { return false; } } } // The number is valid to place return true;}
O(9^(n²)), where n is the size of the Sudoku grid (typically 9).
In the worst case, we need to try all 9 digits for each of the n² cells. However, in practice, the algorithm is much faster because of constraint propagation and early pruning.
O(n²) for the board representation, plus O(n²) for the recursion stack.
We need an n×n grid to represent the Sudoku board, and the recursion stack can go up to depth n² in the worst case (if we fill all cells one by one).
Sudoku is a 9×9 grid-based puzzle where the goal is to fill each cell with digits from 1 to 9 such that:
Sudoku is a perfect example of a constraint satisfaction problem that can be solved using backtracking:
Here's how we can implement the Sudoku solver using backtracking:
O(9^(n²)), where n is the size of the Sudoku grid (typically 9). In the worst case, we need to try all 9 digits for each of the n² cells.
O(n²) for the board representation, plus O(n²) for the recursion stack in the worst case.
Learn how to solve Sudoku puzzles using backtracking.
Sudoku is a 9×9 grid-based puzzle where the goal is to fill each cell with digits from 1 to 9 such that:
Example Sudoku Puzzle:
Sudoku is a perfect candidate for backtracking because:
Each cell must satisfy row, column, and box constraints simultaneously.
We can fill the grid one cell at a time, checking constraints as we go.
We can quickly identify and abandon invalid paths without exploring all possibilities.
A properly designed Sudoku puzzle has exactly one solution, which backtracking can find.
Find an empty cell in the Sudoku grid.
Try placing digits 1-9 in the empty cell.
Check if the digit satisfies all Sudoku constraints.
If valid, recursively try to fill the rest of the grid.
If the recursive call fails, backtrack and try a different digit.
Continue until the entire grid is filled or no solution exists.
Here's how we can implement the Sudoku solver using backtracking:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182function solveSudoku(board) { // Try to solve the Sudoku puzzle solve(board); return board;} function solve(board) { // Find an empty cell const emptyCell = findEmptyCell(board); // If there are no empty cells, the puzzle is solved if (!emptyCell) { return true; } const [row, col] = emptyCell; // Try placing digits 1-9 in the empty cell for (let num = 1; num <= 9; num++) { // Check if it's valid to place the number if (isValid(board, row, col, num)) { // Place the number board[row][col] = num; // Recursively try to solve the rest of the puzzle if (solve(board)) { return true; } // If placing the number doesn't lead to a solution, backtrack board[row][col] = 0; } } // No solution found with the current configuration return false;} function findEmptyCell(board) { // Find the first empty cell (represented by 0) for (let row = 0; row < 9; row++) { for (let col = 0; col < 9; col++) { if (board[row][col] === 0) { return [row, col]; } } } // No empty cells found return null;} function isValid(board, row, col, num) { // Check if the number already exists in the row for (let x = 0; x < 9; x++) { if (board[row][x] === num) { return false; } } // Check if the number already exists in the column for (let y = 0; y < 9; y++) { if (board[y][col] === num) { return false; } } // Check if the number already exists in the 3x3 box const boxRow = Math.floor(row / 3) * 3; const boxCol = Math.floor(col / 3) * 3; for (let y = boxRow; y < boxRow + 3; y++) { for (let x = boxCol; x < boxCol + 3; x++) { if (board[y][x] === num) { return false; } } } // The number is valid to place return true;}
O(9^(n²)), where n is the size of the Sudoku grid (typically 9).
In the worst case, we need to try all 9 digits for each of the n² cells. However, in practice, the algorithm is much faster because of constraint propagation and early pruning.
O(n²) for the board representation, plus O(n²) for the recursion stack.
We need an n×n grid to represent the Sudoku board, and the recursion stack can go up to depth n² in the worst case (if we fill all cells one by one).