Command Palette

Search for a command to run...

Problem 13.10 · BacktrackingHard

Sudoku Solver

What it teaches: Fill empty cells one at a time, check row/column/box constraints in O(1), and backtrack on contradictions.

Practise it on judges as “Sudoku Solver”.

The problem

Fill a 9 × 9 Sudoku board in place ('.' marks empty cells) so every row, column and 3 × 3 box contains digits 1–9 exactly once. The puzzle has exactly one solution.

Example 1

Input: board = the standard example puzzle
Output: the board filled in

Constraints

  • board is 9 × 9
  • Exactly one solution

Pattern clues in the wording

  • → Constraint satisfaction
  • → Each empty cell is a choice among digits

These clues point to Backtracking: Build a candidate one choice at a time; when a choice can't lead to an answer, undo it and try the next.

Stuck? Take one hint at a time

Solution.java · starter
class Solution {
    public void solveSudoku(char[][] board) {
    }
}

Write your solution locally or in your editor for now. The in-browser runner (Java first, then Python, C++ and more) will run these tests right here.

Test cases

#InputExpected
1
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"]]

From slow to fast

Approaches

1

Backtracking with constraint tables

Time Exponential in the worst case; fast in practice Space O(81)

Precompute used[row][d], used[col][d], used[box][d]. Recursively fill cells in order; for an empty cell try digits not used in its row, column or box; return true when all cells are filled; undo on failure.

Approach 1
class Solution {
    private final boolean[][] row = new boolean[9][10], col = new boolean[9][10], box = new boolean[9][10];

    public void solveSudoku(char[][] board) {
        for (int r = 0; r < 9; r++)
            for (int c = 0; c < 9; c++)
                if (board[r][c] != '.') mark(r, c, board[r][c] - '0', true);
        solve(board, 0);
    }

    private boolean solve(char[][] b, int cell) {
        if (cell == 81) return true;
        int r = cell / 9, c = cell % 9;
        if (b[r][c] != '.') return solve(b, cell + 1);
        for (int d = 1; d <= 9; d++) {
            if (row[r][d] || col[c][d] || box[(r / 3) * 3 + c / 3][d]) continue;
            b[r][c] = (char) ('0' + d);
            mark(r, c, d, true);
            if (solve(b, cell + 1)) return true;
            mark(r, c, d, false);
            b[r][c] = '.';
        }
        return false;
    }

    private void mark(int r, int c, int d, boolean v) {
        row[r][d] = v;
        col[c][d] = v;
        box[(r / 3) * 3 + c / 3][d] = v;
    }
}

Verdict: Solves typical puzzles in milliseconds.

Before you submit

Edge cases and common mistakes

Test these inputs

  • Nearly full board
  • Puzzle needing deep backtracking

Mistakes people make

  • Scanning the row, column and box on every check (slower but correct).
  • Wrong box index: (r / 3) * 3 + c / 3.

Interview

Follow-up questions

How do real solvers go faster?