22
33/**
44 * Sudoku Solver using Backtracking Algorithm
5- *
6- * This class solves a partially filled 9×9 Sudoku board by finding a valid arrangement
7- * where every row, column, and 3×3 subgrid contains digits 1-9 exactly once.
8- *
5+ *
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+ *
914 * Time Complexity: O(9^(n*n)) in worst case, where n=9
1015 * Space Complexity: O(n*n) for recursion stack
11- *
16+ *
1217 * @author TheAlgorithms
1318 */
1419public class SudokuSolver {
1520
16- private static final int SIZE = 9 ;
17- private static final int SUBGRID_SIZE = 3 ;
18- private static final int EMPTY = 0 ;
19-
20- /**
21- * Solves the given Sudoku board using backtracking.
22- * Modifies the board in-place.
23- *
24- * @param board 9×9 2D array representing the Sudoku board (0 = empty cell)
25- * @return true if a valid solution exists, false otherwise
26- */
27- public static boolean solveSudoku (int [][] board ) {
28- for (int row = 0 ; row < SIZE ; row ++) {
29- for (int col = 0 ; col < SIZE ; col ++) {
30- // Find an empty cell
31- if (board [row ][col ] == EMPTY ) {
32- // Try digits 1-9
33- for (int num = 1 ; num <= SIZE ; num ++) {
34- if (isValid (board , row , col , num )) {
35- // Place the number
36- board [row ][col ] = num ;
37-
38- // Recursively try to solve the rest
39- if (solveSudoku (board )) {
40- return true ;
41- }
42-
43- // Backtrack if no solution found
44- board [row ][col ] = EMPTY ;
45- }
46- }
47- // No valid number found, backtrack
48- return false ;
49- }
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 ;
5050 }
51+ }
52+ // No valid number found, backtrack
53+ return false ;
5154 }
52- // All cells filled successfully
53- return true ;
55+ }
5456 }
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- // Check row constraint
67- if (!isRowValid (board , row , num )) {
68- return false ;
69- }
70-
71- // Check column constraint
72- if (!isColumnValid (board , col , num )) {
73- return false ;
74- }
75-
76- // Check 3×3 subgrid constraint
77- if (!isSubgridValid (board , row , col , num )) {
78- return false ;
79- }
80-
81- return true ;
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 ;
8274 }
8375
84- /**
85- * Checks if a number already exists in the given row.
86- */
87- private static boolean isRowValid (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 ;
76+ // Check column constraint
77+ if (!isColumnValid (board , col , num )) {
78+ return false ;
9479 }
9580
96- /**
97- * Checks if a number already exists in the given column.
98- */
99- private static boolean isColumnValid (int [][] board , int col , int num ) {
100- for (int row = 0 ; row < SIZE ; row ++) {
101- if (board [row ][col ] == num ) {
102- return false ;
103- }
104- }
105- return true ;
81+ // Check 3×3 subgrid constraint
82+ if (!isSubgridValid (board , row , col , num )) {
83+ return false ;
10684 }
10785
108- /**
109- * Checks if a number already exists in the 3×3 subgrid.
110- */
111- private static boolean isSubgridValid (int [][] board , int row , int col , int num ) {
112- int subgridRow = row - row % SUBGRID_SIZE ;
113- int subgridCol = col - col % SUBGRID_SIZE ;
114-
115- for (int i = subgridRow ; i < subgridRow + SUBGRID_SIZE ; i ++) {
116- for (int j = subgridCol ; j < subgridCol + SUBGRID_SIZE ; j ++) {
117- if (board [i ][j ] == num ) {
118- return false ;
119- }
120- }
121- }
122- return true ;
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+ }
123102 }
124-
125- /**
126- * Prints the Sudoku board in a readable format.
127- */
128- public static void printBoard (int [][] board ) {
129- for (int row = 0 ; row < SIZE ; row ++) {
130- if (row % SUBGRID_SIZE == 0 && row != 0 ) {
131- System .out .println ("-----------" );
132- }
133- for (int col = 0 ; col < SIZE ; col ++) {
134- if (col % SUBGRID_SIZE == 0 && col != 0 ) {
135- System .out .print ("|" );
136- }
137- System .out .print (board [row ][col ]);
138- }
139- System .out .println ();
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+ }
119+ }
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 ;
140141 }
142+ }
141143 }
142-
143- /**
144- * Main method demonstrating Sudoku solver functionality.
145- */
146- public static void main (String [] args ) {
147- // Example Sudoku puzzle (0 = empty cell)
148- int [][] board = {
149- {5 , 3 , 0 , 0 , 7 , 0 , 0 , 0 , 0 },
150- {6 , 0 , 0 , 1 , 9 , 5 , 0 , 0 , 0 },
151- {0 , 9 , 8 , 0 , 0 , 0 , 0 , 6 , 0 },
152- {8 , 0 , 0 , 0 , 6 , 0 , 0 , 0 , 3 },
153- {4 , 0 , 0 , 8 , 0 , 3 , 0 , 0 , 1 },
154- {7 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 6 },
155- {0 , 6 , 0 , 0 , 0 , 0 , 2 , 8 , 0 },
156- {0 , 0 , 0 , 4 , 1 , 9 , 0 , 0 , 5 },
157- {0 , 0 , 0 , 0 , 8 , 0 , 0 , 7 , 9 }
158- };
159-
160- System .out .println ("Sudoku Puzzle:" );
161- printBoard (board );
162-
163- if (solveSudoku (board )) {
164- System .out .println ("\n Solved Sudoku:" );
165- printBoard (board );
166- } else {
167- System .out .println ("\n No solution exists for this Sudoku puzzle." );
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 ("|" );
168160 }
161+ System .out .print (board [row ][col ]);
162+ }
163+ System .out .println ();
164+ }
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 ("\n Solved Sudoku:" );
191+ printBoard (board );
192+ } else {
193+ System .out .println ("\n No solution exists for this Sudoku puzzle." );
169194 }
195+ }
170196}
0 commit comments