Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy these rules: each of the digits 1-9 must occur exactly once in each row, each column, and each of the nine 3x3 sub-boxes of the grid. The character "." indicates an empty cell. Use backtracking that fills the grid cell by cell: try each digit 1-9 in the next empty cell, and prune immediately if that digit already appears in the same row, column, or box — undoing the placement and trying the next digit whenever every option from here leads to a dead end.
Constraints
- board.length == 9
- boardi.length == 9
- boardi[j] is a digit 1-9 or "."
- It is guaranteed that the input board has only one solution
Example
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"]][["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"]]Explanation Every empty cell is filled so that each row, column, and 3x3 box contains the digits 1-9 exactly once.
In plain terms
- 3x3 sub-box
- One of the nine non-overlapping 3-by-3 blocks that tile the 9x9 grid — like a row or column, each box must also contain the digits 1-9 exactly once.
Try each digit in the next empty cell, prune on any conflict
Cell (0,2) is empty. Try 1 — but column 2 already has a 1 at row 6, so this conflicts.
What happens in this step
check digit 1 at row 0, col 2 row 0 so far: 5 3 [1] . 7 . . . . isValid checks three things for this cell: the whole row, the whole column, and the 3x3 box it sits in. 1 is already placed somewhere in column 2, so this placement is rejected before it's even tried — undo and move on to the next candidate digit.
Steps to visualize
- Move to the next empty cell in the grid.
- Try digits 1 through 9 in order, skipping any digit that already appears in this row, column, or 3x3 box.
- Place the first digit that has no conflicts and recurse into the next empty cell.
- If every digit leads to a dead end further on, undo the last placement and try the next digit at the previous cell.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Cell (0,2) is empty. Try 1 — but column 2 already has a 1 at row 6, so this conflicts.
What happens in this step
check digit 1 at row 0, col 2 row 0 so far: 5 3 [1] . 7 . . . . isValid checks three things for this cell: the whole row, the whole column, and the 3x3 box it sits in. 1 is already placed somewhere in column 2, so this placement is rejected before it's even tried — undo and move on to the next candidate digit.
Solution
function solveSudoku(board) {
const grid = board.map((row) => row.slice());
function isValid(row, col, value) {
for (let i = 0; i < 9; i++) {
if (grid[row][i] === value) return false;
if (grid[i][col] === value) return false;
}
const boxRow = Math.floor(row / 3) * 3;
const boxCol = Math.floor(col / 3) * 3;
for (let r = boxRow; r < boxRow + 3; r++) {
for (let c = boxCol; c < boxCol + 3; c++) {
if (grid[r][c] === value) return false;
}
}
return true;
}
function backtrack(pos) {
if (pos === 81) {
return true;
}
const row = Math.floor(pos / 9);
const col = pos % 9;
if (grid[row][col] !== '.') {
return backtrack(pos + 1);
}
for (let digit = 1; digit <= 9; digit++) {
const value = String(digit);
if (isValid(row, col, value)) {
grid[row][col] = value;
if (backtrack(pos + 1)) {
return true;
}
grid[row][col] = '.'; // undo
}
}
return false;
}
backtrack(0);
return grid;
}- Time
- O(9^m) where m is the number of empty cells
- Space
- O(1) beyond the grid
Test cases
| Input | Expected | Covers |
|---|---|---|
the classic 9x9 puzzle from the docstring | the fully solved 9x9 grid | example from the docstring |
the solved grid with only (row 0, col 2) blanked out | the same fully solved 9x9 grid, with 4 restored at (0, 2) | a single empty cell forced by its row, column, and box |
the solved grid with (row 1, col 1) and (row 1, col 2) blanked out | the same fully solved 9x9 grid, with 7 and 2 restored | two adjacent empty cells in the same row, each forced by column and box |
the solved grid with only (row 8, col 0) blanked out | the same fully solved 9x9 grid, with 3 restored at (8, 0) | a single empty cell forced within the bottom-left box |