All questions

Sudoku Solver

Premium

Sudoku Solver

Sudoku is a number-placement puzzle: fill a 9×9 grid so that every row, every column, and each of the nine 3×3 boxes contains the digits 1 through 9 exactly once. You are handed a partially filled board — a 0 marks an empty cell, and the digits 19 are fixed clues — and must complete it. This is LeetCode 37; every puzzle you receive is guaranteed to have exactly one solution. See Sudoku for the rules and history.

Signature

sudokuSolver(board)  // board: number[][], a 9x9 grid; 0 = empty, 1..9 = clues
                     // fills the board IN PLACE and returns the same board

You mutate the grid you are given and return that same reference — not a fresh copy.

Examples

// The board is a 9x9 array of numbers. A 0 is an empty cell to fill.
const board = [
  [5, 3, 0,  0, 7, 0,  0, 0, 0],
  [6, 0, 0,  1, 9, 5,  0, 0, 0],
  [0, 9, 8,  0, 0, 0,  0, 6, 0],
  [8, 0, 0,  0, 6, 0,  0, 0, 3],
  [4, 0, 0,  8, 0, 3,  0, 0, 1],
  [7, 0, 0,  0, 2, 0,  0, 0, 6],
  [0, 6, 0,  0, 0, 0,  2, 8, 0],
  [0, 0, 0,  4, 1, 9,  0, 0, 5],
  [0, 0, 0,  0, 8, 0,  0, 7, 9],
];

const solved = sudokuSolver(board);
solved === board; // true — the same array, now filled in

// solved is:
// [
//   [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],
// ]

Notes

  • One solution guaranteed — each puzzle has exactly one valid completion, so you never choose between competing answers, and you will never be handed an unsolvable grid.
  • Solve in place — write into the board you were given and return that same reference. Do not build and return a new grid.
  • The three constraints — a digit may go in a cell only if it does not already appear in that cell's row, its column, or its 3×3 box. All three must hold at once.
  • The 3×3 box — the box that contains cell (r, c) has its top-left corner at row 3 * Math.floor(r / 3) and column 3 * Math.floor(c / 3); its nine cells span that corner plus the next two rows and columns.
  • Digits, not strings — cells hold the numbers 19, with 0 for empty. You do not need to validate the input or handle any grid shape other than 9×9.

FAQ

What is the time complexity of the backtracking solver?
In the worst case it is exponential in the number of empty cells, since each blank can branch up to nine ways. In practice, pruning every placement against its row, column, and box eliminates almost all of those branches, so a standard puzzle solves in milliseconds.
Why check validity before recursing instead of validating the finished grid?
Checking first (pruning) throws out an illegal digit immediately, so the search never fills dozens of cells on top of a grid that already breaks a rule. That single change is what turns an intractable brute force into a fast solve.
How do you find which 3x3 box a cell belongs to?
The box's top-left corner is at row 3 * Math.floor(r / 3) and column 3 * Math.floor(c / 3): flooring the index divided by three snaps it to the start of its band of three. The box's 0-to-8 index is 3 * Math.floor(r / 3) + Math.floor(c / 3).

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium