Sudoku Solver
Sudoku Solver is LeetCode 37 (Hard). You get a 9 × 9 board of characters: the digits '1' to '9' for given cells and '.' for empty ones. Fill every empty cell so the whole board becomes a valid Sudoku.
- Every row must hold each digit
1–9exactly once. - Every column must hold each digit exactly once.
- Every one of the nine 3 × 3 boxes must hold each digit exactly once.
- Change
boardin place; the function returns nothing.
The sudoku solver LeetCode version guarantees the input has exactly one solution. The board size is fixed, but dozens of cells can be empty, each with up to 9 candidate digits, so blind guessing is hopeless: the solver has to reject a digit the moment it breaks a rule.
- board.length == 9
- board[i].length == 9
- board[i][j] is a digit or '.'.
- It is guaranteed that the input board has only one solution.
Intuition
A sudoku solver is a search: some empty cell needs a digit, and the rules only say which digits are not allowed. So guess, and undo the guess when it leads nowhere. That is backtracking, and it is how a step by step sudoku solver works: fill cells one at a time, and when a later cell has no legal digit, an earlier guess was wrong.
Two details make it fast enough. A set of used digits for each row, column and box makes every legality check O(1) instead of a 27-cell scan. And the rules prune hard: most digits are rejected immediately, so a real puzzle never comes close to the worst case.
Fill a grid or a sequence under constraints, where a choice can only be judged by what it allows later: backtracking with constraint sets. N-Queens (51) is the same shape with columns and diagonals.
Approach
Before reading on, decide what three pieces of state let you check a digit at (r, c) without scanning, and how to compute the box number from r and c.
Record the given digits
Make rows[9], cols[9], boxes[9] sets. For every filled cell add its digit to all three, and collect every empty cell into a list. The box of (r, c) is (r // 3) * 3 + c // 3.
In the sudoku solver Python code the sets hold the characters '1' to '9' straight from the board. The C++ and Java versions convert with ch - '0' and use boolean arrays indexed by digit instead.
Solve the k-th empty cell
k == len(empty)– every cell is filled: returnTrue.- Otherwise take
(r, c) = empty[k]and loopdover'1'to'9', skipping anydfound inrows[r],cols[c]orboxes[b].
Place, recurse, undo
- Place: write
don the board and add it to the three sets. - Recurse: if
solve(k + 1)returnsTrue, returnTrueimmediately, leaving the digit in place. - Undo: otherwise erase
dfrom the board and the three sets, and try the next digit.
Report a dead end
If the loop ends without success, no digit works in this cell given the earlier guesses. Return False, and the previous cell undoes its guess. Because the puzzle has a solution, the first call eventually returns True.
Sudoku Solver solution in Python | C++ | Java
False and let the previous cell change its guess.False and let the previous cell change its guess.solve returns True all the way up and no guess is undone. Every row, column and box now holds 1 to 4 exactly once. The board was edited in place, which is what LeetCode checks.solve returns True all the way up and no guess is undone. Every row, column and box now holds 1 to 4 exactly once. The board was edited in place, which is what LeetCode checks.Common pitfalls
Undoing the board but not the sets
board[r][c] = "."
board[r][c] = "." rows[r].remove(d) cols[c].remove(d) boxes[b].remove(d)
The sets would still say d is used, so later cells in that row, column and box wrongly reject it. The solver then reports no solution for a valid puzzle.
Not stopping when the board is solved
solve(k + 1) board[r][c] = "."
if solve(k + 1):
return True
board[r][c] = "."Without checking the result, every placement is undone on the way back up, and the board ends exactly as it started. The success has to propagate up and skip every undo.
Wrong box index
b = r // 3 + c // 3
b = r // 3 * 3 + c // 3
r // 3 + c // 3 gives only 5 distinct values (0 to 4), merging different boxes. Boxes are numbered row-major: box row times 3, plus box column.
Complexity
Sudoku Solver FAQ
What is the difference between Valid Sudoku and Sudoku Solver?
Valid Sudoku (LeetCode 36) only checks that the filled cells break no rule: a single pass with the same row, column and box sets. Sudoku Solver (37) must fill the empty cells, which needs the search and backtracking on top of those checks.
How can a sudoku solver be made faster?
- Most constrained cell first: instead of reading order, fill the empty cell with the fewest legal digits. A cell with one option is forced, and dead ends show up much earlier.
- Bitmasks: one 9-bit integer per row, column and box replaces the sets; the legal digits for a cell are one OR and one NOT away.
- Exact cover: Dancing Links (Algorithm X) treats Sudoku as 324 constraints and handles the hardest puzzles, at the cost of much more code.
None of these is needed for LeetCode 37; plain backtracking passes comfortably.