11package 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 */
199public 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 ("\n Solved Sudoku:" );
191- printBoard (board );
192- } else {
193- System .out .println ("\n No 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