11package com .thealgorithms .backtracking ;
22
33/**
4- * Sudoku Solver using Backtracking Algorithm
4+ * SudokuSolver implements the backtracking algorithm to solve a standard 9×9 Sudoku puzzle.
5+ * The puzzle is represented as a 2D array where 0 indicates an empty cell.
56 *
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.
7+ * <p>Algorithm:
8+ * - Iterates through empty cells and tries numbers 1-9
9+ * - Validates placement against row, column, and 3×3 subgrid constraints
10+ * - Backtracks if no valid number is found
11+ * - Returns true if a solution exists
912 *
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
13+ * <p>Wikipedia: https://en.wikipedia.org/wiki/Sudoku_solving_algorithms
1614 *
1715 * @author TheAlgorithms
1816 */
19- public class SudokuSolver {
20-
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- if (board [row ][col ] == EMPTY ) {
36- for (int num = 1 ; num <= SIZE ; num ++) {
37- if (isValid (board , row , col , num )) {
38- board [row ][col ] = num ;
39-
40- if (solveSudoku (board )) {
41- return true ;
42- }
43-
44- board [row ][col ] = EMPTY ;
17+ public final class SudokuSolver {
18+
19+ private static final int SIZE = 9 ;
20+ private static final int SUBGRID_SIZE = 3 ;
21+ private static final int EMPTY = 0 ;
22+
23+ private SudokuSolver () {
24+ // Utility class - prevent instantiation
25+ }
26+
27+ /**
28+ * Solves the given Sudoku board using backtracking. Modifies the board
29+ * in-place.
30+ *
31+ * @param board 9×9 2D array representing the Sudoku board (0 = empty cell)
32+ * @return true if a valid solution exists, false otherwise
33+ */
34+ public static boolean solveSudoku (int [][] board ) {
35+ for (int row = 0 ; row < SIZE ; row ++) {
36+ for (int col = 0 ; col < SIZE ; col ++) {
37+ if (board [row ][col ] == EMPTY ) {
38+ for (int num = 1 ; num <= SIZE ; num ++) {
39+ if (isValid (board , row , col , num )) {
40+ board [row ][col ] = num ;
41+
42+ if (solveSudoku (board )) {
43+ return true ;
44+ }
45+
46+ board [row ][col ] = EMPTY ;
47+ }
48+ }
49+ return false ;
50+ }
4551 }
46- }
47- return false ;
4852 }
49- }
53+ return true ;
5054 }
51- return true ;
52- }
53-
54- /**
55- * Checks if placing a number at a given position is valid.
56- *
57- * @param board the Sudoku board
58- * @param row row index
59- * @param col column index
60- * @param num number to place (1-9)
61- * @return true if placement is valid
62- */
63- private static boolean isValid (int [][] board , int row , int col , int num ) {
64- return isRowValid (board , row , num )
65- && isColumnValid (board , col , num )
66- && isSubgridValid (board , row , col , num );
67- }
68-
69- /**
70- * Checks if a number already exists in the given row.
71- *
72- * @param board the Sudoku board
73- * @param row row index
74- * @param num number to check
75- * @return true if number is not in row
76- */
77- private static boolean isRowValid (int [][] board , int row , int num ) {
78- for (int col = 0 ; col < SIZE ; col ++) {
79- if (board [row ][col ] == num ) {
80- return false ;
81- }
55+
56+ /**
57+ * Checks if placing a number at a given position is valid.
58+ *
59+ * @param board the Sudoku board
60+ * @param row row index
61+ * @param col column index
62+ * @param num number to place (1-9)
63+ * @return true if placement is valid
64+ */
65+ private static boolean isValid (int [][] board , int row , int col , int num ) {
66+ return isRowValid (board , row , num ) && isColumnValid (board , col , num ) && isSubgridValid (board , row , col , num );
67+ }
68+
69+ /**
70+ * Checks if a number already exists in the given row.
71+ *
72+ * @param board the Sudoku board
73+ * @param row row index
74+ * @param num number to check
75+ * @return true if number is not in row
76+ */
77+ private static boolean isRowValid (int [][] board , int row , int num ) {
78+ for (int col = 0 ; col < SIZE ; col ++) {
79+ if (board [row ][col ] == num ) {
80+ return false ;
81+ }
82+ }
83+ return true ;
8284 }
83- return true ;
84- }
85-
86- /* *
87- * Checks if a number already exists in the given column.
88- *
89- * @param board the Sudoku board
90- * @param col column index
91- * @param num number to check
92- * @return true if number is not in column
93- */
94- private static boolean isColumnValid ( int [][] board , int col , int num ) {
95- for ( int row = 0 ; row < SIZE ; row ++) {
96- if ( board [ row ][ col ] == num ) {
97- return false ;
98- }
85+
86+ /**
87+ * Checks if a number already exists in the given column.
88+ *
89+ * @param board the Sudoku board
90+ * @param col column index
91+ * @param num number to check
92+ * @return true if number is not in column
93+ */
94+ private static boolean isColumnValid ( int [][] board , int col , int num ) {
95+ for ( int row = 0 ; row < SIZE ; row ++) {
96+ if ( board [ row ][ col ] == num ) {
97+ return false ;
98+ }
99+ }
100+ return true ;
99101 }
100- return true ;
101- }
102-
103- /**
104- * Checks if a number already exists in the 3×3 subgrid.
105- *
106- * @param board the Sudoku board
107- * @param row row index
108- * @param col column index
109- * @param num number to check
110- * @return true if number is not in subgrid
111- */
112- private static boolean isSubgridValid (
113- int [][] board , int row , int col , int num ) {
114- int subgridRow = row - row % SUBGRID_SIZE ;
115- int subgridCol = col - col % SUBGRID_SIZE ;
116-
117- for (int i = subgridRow ; i < subgridRow + SUBGRID_SIZE ; i ++) {
118- for (int j = subgridCol ; j < subgridCol + SUBGRID_SIZE ; j ++) {
119- if (board [i ][j ] == num ) {
120- return false ;
102+
103+ /**
104+ * Checks if a number already exists in the 3×3 subgrid.
105+ *
106+ * @param board the Sudoku board
107+ * @param row row index
108+ * @param col column index
109+ * @param num number to check
110+ * @return true if number is not in subgrid
111+ */
112+ private static boolean isSubgridValid (int [][] board , int row , int col , int num ) {
113+ int subgridRow = row - row % SUBGRID_SIZE ;
114+ int subgridCol = col - col % SUBGRID_SIZE ;
115+
116+ for (int i = subgridRow ; i < subgridRow + SUBGRID_SIZE ; i ++) {
117+ for (int j = subgridCol ; j < subgridCol + SUBGRID_SIZE ; j ++) {
118+ if (board [i ][j ] == num ) {
119+ return false ;
120+ }
121+ }
121122 }
122- }
123+ return true ;
123124 }
124- return true ;
125- }
126-
127- /**
128- * Prints the Sudoku board in a readable format.
129- *
130- * @param board the Sudoku board to print
131- */
132- public static void printBoard (int [][] board ) {
133- for (int row = 0 ; row < SIZE ; row ++) {
134- if (row % SUBGRID_SIZE == 0 && row != 0 ) {
135- System .out .println ("-----------" );
136- }
137- for (int col = 0 ; col < SIZE ; col ++) {
138- if (col % SUBGRID_SIZE == 0 && col != 0 ) {
139- System .out .print ("|" );
125+
126+ /**
127+ * Prints the Sudoku board in a readable format.
128+ *
129+ * @param board the Sudoku board to print
130+ */
131+ public static void printBoard (int [][] board ) {
132+ for (int row = 0 ; row < SIZE ; row ++) {
133+ if (row % SUBGRID_SIZE == 0 && row != 0 ) {
134+ System .out .println ("-----------" );
135+ }
136+ for (int col = 0 ; col < SIZE ; col ++) {
137+ if (col % SUBGRID_SIZE == 0 && col != 0 ) {
138+ System .out .print ("|" );
139+ }
140+ System .out .print (board [row ][col ]);
141+ }
142+ System .out .println ();
140143 }
141- System .out .print (board [row ][col ]);
142- }
143- System .out .println ();
144144 }
145- }
146-
147- /**
148- * Main method demonstrating Sudoku solver functionality.
149- *
150- * @param args command line arguments (not used)
151- */
152- public static void main (String [] args ) {
153- int [][] board = {
154- {5 , 3 , 0 , 0 , 7 , 0 , 0 , 0 , 0 },
155- {6 , 0 , 0 , 1 , 9 , 5 , 0 , 0 , 0 },
156- {0 , 9 , 8 , 0 , 0 , 0 , 0 , 6 , 0 },
157- {8 , 0 , 0 , 0 , 6 , 0 , 0 , 0 , 3 },
158- {4 , 0 , 0 , 8 , 0 , 3 , 0 , 0 , 1 },
159- {7 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 6 },
160- {0 , 6 , 0 , 0 , 0 , 0 , 2 , 8 , 0 },
161- {0 , 0 , 0 , 4 , 1 , 9 , 0 , 0 , 5 },
162- {0 , 0 , 0 , 0 , 8 , 0 , 0 , 7 , 9 }
163- };
164-
165- System .out .println ("Sudoku Puzzle:" );
166- printBoard (board );
167-
168- if (solveSudoku (board )) {
169- System .out .println ("\n Solved Sudoku:" );
170- printBoard (board );
171- } else {
172- System .out .println ("\n No solution exists for this Sudoku puzzle." );
145+
146+ /**
147+ * Main method demonstrating Sudoku solver functionality.
148+ *
149+ * @param args command line arguments (not used)
150+ */
151+ public static void main (String [] args ) {
152+ int [][] 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 }};
153+
154+ System .out .println ("Sudoku Puzzle:" );
155+ printBoard (board );
156+
157+ if (solveSudoku (board )) {
158+ System .out .println ("\n Solved Sudoku:" );
159+ printBoard (board );
160+ } else {
161+ System .out .println ("\n No solution exists for this Sudoku puzzle." );
162+ }
173163 }
174- }
175- }
164+ }
165+
0 commit comments