Sudoku Solver
Problem Statement
Embark on a challenge to solve a 9×9 Sudoku puzzle! Given a partially filled grid, fill every empty cell (marked with '.') with digits 1-9 so that each row, column, and 3×3 subgrid contains all digits exactly once. This hard-level problem harnesses the power of backtracking to explore all possibilities—imagine being a detective piecing together a numeric masterpiece, ensuring no rule is broken!
Example
Input: A 9×9 board:
[
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
Output: Solved board (one possible solution):
[
["5","3","4","6","7","8","9","1","2"],
["6","7","2","1","9","5","3","4","8"],
["1","9","8","3","4","2","5","6","7"],
["8","5","9","7","6","1","4","2","3"],
["4","2","6","8","5","3","7","9","1"],
["7","1","3","9","2","4","8","5","6"],
["9","6","1","5","3","7","2","8","4"],
["2","8","7","4","1","9","6","3","5"],
["3","4","5","2","8","6","1","7","9"]
]
The output satisfies all Sudoku rules: no digit repeats in any row, column, or 3×3 subgrid.
Code
Java
Python
JavaScript
public class Solution {
public void solveSudoku(char[][] board) {
solve(board);
}
private boolean solve(char[][] board) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (board[row][col] == '.') {
for (char c = '1'; c <= '9'; c++) {
if (isValid(board, row, col, c)) {
board[row][col] = c;
if (solve(board)) return true;
board[row][col] = '.'; // Backtrack
}
}
return false; // No valid number found
}
}
}
return true; // Board is fully filled
}
private boolean isValid(char[][] board, int row, int col, char c) {
for (int x = 0; x < 9; x++) {
// Check row, column, and 3x3 subgrid
if (board[row][x] == c || board[x][col] == c ||
board[row - row % 3 + x / 3][col - col % 3 + x % 3] == c) {
return false;
}
}
return true;
}
}
def solve_sudoku(board):
def solve():
for i in range(9):
for j in range(9):
if board[i][j] == ".":
for c in "123456789":
if is_valid(i, j, c):
board[i][j] = c
if solve():
return True
board[i][j] = "." # Backtrack
return False # No valid number found
return True # Board is fully filled
def is_valid(row, col, c):
for x in range(9):
# Check row
if board[row][x] == c:
return False
# Check column
if board[x][col] == c:
return False
# Check 3x3 subgrid
if board[3 * (row // 3) + x // 3][3 * (col // 3) + x % 3] == c:
return False
return True
solve()
return board # Modified in-place
# Example usage (simplified for display)
board = [
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
solve_sudoku(board)
for row in board:
print(row) # Outputs the solved board
function solveSudoku(board) {
function solve() {
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (board[i][j] === ".") {
for (let c = "1"; c <= "9"; c++) {
if (isValid(i, j, c)) {
board[i][j] = c;
if (solve()) return true;
board[i][j] = "."; // Backtrack
}
}
return false; // No valid number found
}
}
}
return true; // Board is fully filled
}
function isValid(row, col, c) {
for (let x = 0; x < 9; x++) {
// Check row
if (board[row][x] === c) return false;
// Check column
if (board[x][col] === c) return false;
// Check 3x3 subgrid
if (board[Math.floor(row / 3) * 3 + Math.floor(x / 3)]
[Math.floor(col / 3) * 3 + x % 3] === c) return false;
}
return true;
}
solve();
return board; // Modified in-place
}
// Example usage
const board = [
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
];
solveSudoku(board);
console.log(board); // Outputs the solved board
Explanation
- Base Case: If the board is fully filled (no '.' remains), return true—puzzle solved!
- Backtracking: For each empty cell, try digits 1-9; if valid, place it and recurse.
- Validation: Check the row, column, and 3×3 subgrid for conflicts before placing a digit.
- Flow Example: Start at (0,2) → try '4' → valid → recurse → next empty → try '6', etc., backtracking if a path fails.
- In-Place: Modifies the board directly, undoing moves (replacing with '.') when a path dead-ends.
- Success: Stops at the first valid solution (Sudoku puzzles typically have one unique solution).
Note
Time complexity is O(9^(N)) where N is the number of empty cells (exponential due to trying all possibilities), though pruning reduces this in practice. Space complexity is O(81) or O(1) for the 9×9 board plus O(N) for the call stack. It’s a brain-teasing triumph of logic and persistence!
