Skip to content

Commit a9eee45

Browse files
committed
Add Sudoku Solver using Backtracking algorithm
1 parent 8d51415 commit a9eee45

File tree

2 files changed

+199
-263
lines changed

2 files changed

+199
-263
lines changed
Lines changed: 119 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,196 +1,140 @@
11
package com.thealgorithms.backtracking;
22

33
/**
4-
* Sudoku Solver using Backtracking Algorithm
4+
* Sudoku Solver using Backtracking Algorithm.
55
*
6-
* This class solves a partially filled 9×9 Sudoku board by finding a valid
7-
* arrangement where every row, column, and 3×3 subgrid contains digits 1-9
8-
* exactly once.
9-
*
10-
* Algorithm References:
11-
* - Backtracking: https://en.wikipedia.org/wiki/Backtracking
12-
* - Sudoku: https://en.wikipedia.org/wiki/Sudoku
13-
*
14-
* Time Complexity: O(9^(n*n)) in worst case, where n=9
15-
* Space Complexity: O(n*n) for recursion stack
16-
*
17-
* @author TheAlgorithms
6+
* Solves a 9×9 Sudoku grid by filling empty cells (0) such that every row,
7+
* column, and 3×3 subgrid contains all digits 1–9 exactly once.
188
*/
199
public class SudokuSolver {
2010

21-
private static final int SIZE = 9;
22-
private static final int SUBGRID_SIZE = 3;
23-
private static final int EMPTY = 0;
24-
25-
/**
26-
* Solves the given Sudoku board using backtracking. Modifies the board
27-
* in-place.
28-
*
29-
* @param board 9×9 2D array representing the Sudoku board (0 = empty cell)
30-
* @return true if a valid solution exists, false otherwise
31-
*/
32-
public static boolean solveSudoku(int[][] board) {
33-
for (int row = 0; row < SIZE; row++) {
34-
for (int col = 0; col < SIZE; col++) {
35-
// Find an empty cell
36-
if (board[row][col] == EMPTY) {
37-
// Try digits 1-9
38-
for (int num = 1; num <= SIZE; num++) {
39-
if (isValid(board, row, col, num)) {
40-
// Place the number
41-
board[row][col] = num;
42-
43-
// Recursively try to solve the rest
44-
if (solveSudoku(board)) {
45-
return true;
46-
}
47-
48-
// Backtrack if no solution found
49-
board[row][col] = EMPTY;
50-
}
51-
}
52-
// No valid number found, backtrack
53-
return false;
11+
private static final int SIZE = 9;
12+
private static final int SUBGRID = 3;
13+
private static final int EMPTY = 0;
14+
15+
/**
16+
* Public API: Validates the initial board and triggers the solver.
17+
*
18+
* @param board 9×9 Sudoku grid
19+
* @return true if solvable
20+
*/
21+
public static boolean solveSudoku(int[][] board) {
22+
if (!isInitialBoardValid(board)) {
23+
return false;
5424
}
55-
}
56-
}
57-
// All cells filled successfully
58-
return true;
59-
}
60-
61-
/**
62-
* Checks if placing a number at a given position is valid.
63-
*
64-
* @param board the Sudoku board
65-
* @param row row index
66-
* @param col column index
67-
* @param num number to place (1-9)
68-
* @return true if placement is valid
69-
*/
70-
private static boolean isValid(int[][] board, int row, int col, int num) {
71-
// Check row constraint
72-
if (!isRowValid(board, row, num)) {
73-
return false;
25+
return solve(board);
7426
}
7527

76-
// Check column constraint
77-
if (!isColumnValid(board, col, num)) {
78-
return false;
28+
/**
29+
* Solves Sudoku recursively using backtracking.
30+
*/
31+
private static boolean solve(int[][] board) {
32+
for (int row = 0; row < SIZE; row++) {
33+
for (int col = 0; col < SIZE; col++) {
34+
35+
if (board[row][col] == EMPTY) {
36+
37+
for (int num = 1; num <= SIZE; num++) {
38+
39+
if (isValid(board, row, col, num)) {
40+
board[row][col] = num;
41+
42+
if (solve(board)) {
43+
return true;
44+
}
45+
46+
board[row][col] = EMPTY;
47+
}
48+
}
49+
50+
return false;
51+
}
52+
}
53+
}
54+
return true;
7955
}
8056

81-
// Check 3×3 subgrid constraint
82-
if (!isSubgridValid(board, row, col, num)) {
83-
return false;
57+
/**
58+
* Validates initial puzzle (checks duplicates in rows/cols/subgrids).
59+
*/
60+
public static boolean isInitialBoardValid(int[][] board) {
61+
for (int row = 0; row < SIZE; row++) {
62+
for (int col = 0; col < SIZE; col++) {
63+
64+
int num = board[row][col];
65+
66+
if (num != EMPTY) {
67+
board[row][col] = EMPTY;
68+
69+
if (!isValid(board, row, col, num)) {
70+
board[row][col] = num;
71+
return false;
72+
}
73+
74+
board[row][col] = num;
75+
}
76+
}
77+
}
78+
return true;
8479
}
8580

86-
return true;
87-
}
88-
89-
/**
90-
* Checks if a number already exists in the given row.
91-
*
92-
* @param board the Sudoku board
93-
* @param row row index
94-
* @param num number to check
95-
* @return true if number is not in row
96-
*/
97-
private static boolean isRowValid(int[][] board, int row, int num) {
98-
for (int col = 0; col < SIZE; col++) {
99-
if (board[row][col] == num) {
100-
return false;
101-
}
81+
private static boolean isValid(int[][] board, int row, int col, int num) {
82+
return isRowOk(board, row, num)
83+
&& isColOk(board, col, num)
84+
&& isSubgridOk(board, row, col, num);
10285
}
103-
return true;
104-
}
105-
106-
/**
107-
* Checks if a number already exists in the given column.
108-
*
109-
* @param board the Sudoku board
110-
* @param col column index
111-
* @param num number to check
112-
* @return true if number is not in column
113-
*/
114-
private static boolean isColumnValid(int[][] board, int col, int num) {
115-
for (int row = 0; row < SIZE; row++) {
116-
if (board[row][col] == num) {
117-
return false;
118-
}
86+
87+
private static boolean isRowOk(int[][] board, int row, int num) {
88+
for (int col = 0; col < SIZE; col++) {
89+
if (board[row][col] == num) {
90+
return false;
91+
}
92+
}
93+
return true;
11994
}
120-
return true;
121-
}
122-
123-
/**
124-
* Checks if a number already exists in the 3×3 subgrid.
125-
*
126-
* @param board the Sudoku board
127-
* @param row row index
128-
* @param col column index
129-
* @param num number to check
130-
* @return true if number is not in subgrid
131-
*/
132-
private static boolean isSubgridValid(int[][] board, int row, int col,
133-
int num) {
134-
int subgridRow = row - row % SUBGRID_SIZE;
135-
int subgridCol = col - col % SUBGRID_SIZE;
136-
137-
for (int i = subgridRow; i < subgridRow + SUBGRID_SIZE; i++) {
138-
for (int j = subgridCol; j < subgridCol + SUBGRID_SIZE; j++) {
139-
if (board[i][j] == num) {
140-
return false;
95+
96+
private static boolean isColOk(int[][] board, int col, int num) {
97+
for (int row = 0; row < SIZE; row++) {
98+
if (board[row][col] == num) {
99+
return false;
100+
}
141101
}
142-
}
102+
return true;
143103
}
144-
return true;
145-
}
146-
147-
/**
148-
* Prints the Sudoku board in a readable format.
149-
*
150-
* @param board the Sudoku board to print
151-
*/
152-
public static void printBoard(int[][] board) {
153-
for (int row = 0; row < SIZE; row++) {
154-
if (row % SUBGRID_SIZE == 0 && row != 0) {
155-
System.out.println("-----------");
156-
}
157-
for (int col = 0; col < SIZE; col++) {
158-
if (col % SUBGRID_SIZE == 0 && col != 0) {
159-
System.out.print("|");
104+
105+
private static boolean isSubgridOk(int[][] board, int row, int col, int num) {
106+
int startRow = row - (row % SUBGRID);
107+
int startCol = col - (col % SUBGRID);
108+
109+
for (int i = startRow; i < startRow + SUBGRID; i++) {
110+
for (int j = startCol; j < startCol + SUBGRID; j++) {
111+
if (board[i][j] == num) {
112+
return false;
113+
}
114+
}
160115
}
161-
System.out.print(board[row][col]);
162-
}
163-
System.out.println();
116+
return true;
164117
}
165-
}
166-
167-
/**
168-
* Main method demonstrating Sudoku solver functionality.
169-
*
170-
* @param args command line arguments (not used)
171-
*/
172-
public static void main(String[] args) {
173-
// Example Sudoku puzzle (0 = empty cell)
174-
int[][] board = {
175-
{5, 3, 0, 0, 7, 0, 0, 0, 0},
176-
{6, 0, 0, 1, 9, 5, 0, 0, 0},
177-
{0, 9, 8, 0, 0, 0, 0, 6, 0},
178-
{8, 0, 0, 0, 6, 0, 0, 0, 3},
179-
{4, 0, 0, 8, 0, 3, 0, 0, 1},
180-
{7, 0, 0, 0, 2, 0, 0, 0, 6},
181-
{0, 6, 0, 0, 0, 0, 2, 8, 0},
182-
{0, 0, 0, 4, 1, 9, 0, 0, 5},
183-
{0, 0, 0, 0, 8, 0, 0, 7, 9}
184-
};
185-
186-
System.out.println("Sudoku Puzzle:");
187-
printBoard(board);
188-
189-
if (solveSudoku(board)) {
190-
System.out.println("\nSolved Sudoku:");
191-
printBoard(board);
192-
} else {
193-
System.out.println("\nNo solution exists for this Sudoku puzzle.");
118+
119+
/**
120+
* Utility: Print Sudoku grid.
121+
*/
122+
public static void printBoard(int[][] board) {
123+
for (int row = 0; row < SIZE; row++) {
124+
125+
if (row % SUBGRID == 0 && row != 0) {
126+
System.out.println("-----------");
127+
}
128+
129+
for (int col = 0; col < SIZE; col++) {
130+
131+
if (col % SUBGRID == 0 && col != 0) {
132+
System.out.print("|");
133+
}
134+
135+
System.out.print(board[row][col]);
136+
}
137+
System.out.println();
138+
}
194139
}
195-
}
196-
}
140+
}

0 commit comments

Comments
 (0)