Sudoku Solver in Java
Problem
Solving a Sudoku puzzle means filling every empty cell with a digit from 1 to 9 so that no digit repeats in any row, column, or 3 by 3 box — a digit that later turns out to block every remaining cell has to be undone and a different one tried.
Given a partially-filled 9 by 9 grid, fill in every empty cell so the completed grid satisfies Sudoku's row, column, and box rules.
Java Program
public class SudokuSolver {
static boolean isValid(int[][] board, int row, int col, int num) {
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num) return false;
}
int boxRow = (row / 3) * 3, boxCol = (col / 3) * 3;
for (int r = boxRow; r < boxRow + 3; r++) {
for (int c = boxCol; c < boxCol + 3; c++) {
if (board[r][c] == num) return false;
}
}
return true;
}
static boolean solve(int[][] board) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (board[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValid(board, row, col, num)) {
board[row][col] = num;
if (solve(board)) return true;
board[row][col] = 0; // backtrack: this digit didn't lead to a solution
}
}
return false; // no digit worked for this cell
}
}
}
return true; // no empty cells left
}
public static void main(String[] args) {
int[][] board = {
{0, 2, 0, 4, 0, 6, 0, 8, 0},
{4, 0, 6, 0, 8, 0, 1, 0, 3},
{0, 8, 0, 1, 0, 3, 0, 5, 0},
{2, 0, 4, 0, 6, 0, 8, 0, 1},
{0, 6, 0, 8, 0, 1, 0, 3, 0},
{8, 0, 1, 0, 3, 0, 5, 0, 7},
{0, 4, 0, 6, 0, 8, 0, 1, 0},
{6, 0, 8, 0, 1, 0, 3, 0, 5},
{0, 1, 0, 3, 0, 5, 0, 7, 0}
};
solve(board);
StringBuilder sb = new StringBuilder();
for (int[] row : board) {
for (int i = 0; i < row.length; i++) {
if (i > 0) sb.append(" ");
sb.append(row[i]);
}
sb.append("\n");
}
System.out.print(sb);
}
}Output
Core Logic
Scanning for the next empty cell, trying every digit that doesn't immediately break a rule, and recursing on the rest of the grid fills the whole puzzle one cell at a time, undoing a digit only when it leads nowhere.
- 1
isValid(board, row, col, num)checks whethernumalready appears in that row, that column, or that cell's 3×3 box — placing it is only safe if none of those three checks find a match. - 2
solve(board)scans row by row for the first empty cell (marked0) and tries every digit1through9in it. - 3Placing a valid digit and recursing lets the rest of the grid attempt to complete around that choice; if the recursive call succeeds, the whole grid is solved and
truepropagates back up immediately. - 4If every digit fails to lead to a full solution, the cell is reset to
0— the backtrack step — andfalseis returned so the caller tries its own next digit instead.
Key Point: Returning false only when every digit 1 through 9 has been tried and failed is what guarantees the search is exhaustive — no valid completion is ever skipped, even though most invalid digits are ruled out almost immediately by isValid().
Why: In the absolute worst case, each of the m empty cells could require trying up to 9 digits before the constraint checks and backtracking narrow things down — an enormous, deliberately loose upper bound, since in practice the row/column/box checks prune the vast majority of digit choices almost immediately for a well-posed puzzle; the grid is modified in place, so no extra memory grows with the puzzle's difficulty.