11package com .thealgorithms .backtracking ;
22
33/**
4- * Sudoku Solver using Backtracking Algorithm
5- * Solves a 9x9 Sudoku puzzle by filling empty cells with valid digits (1-9)
4+ * The {@code SudokuSolver} class provides a solution to Sudoku puzzles
5+ * Solves the puzzle by a depth-first backtracking algorithm.
66 *
7- * @author Navadeep0007
7+ * The algorithm fills empty cells (represented by 0) by trying digits 1-9
8+ * and recursively verifying if they lead to a valid solution.
9+ *
10+ * Time Complexity: O(9^{n*n}) where n is the dimension of the grid.
11+ * Space Complexity: O(n*n) to store the board and recursion stack.
12+ *
13+ * @author subhammohanty-sys
814 */
9- public final class SudokuSolver {
1015
11- private static final int GRID_SIZE = 9 ;
12- private static final int SUBGRID_SIZE = 3 ;
13- private static final int EMPTY_CELL = 0 ;
16+ public class SudokuSolver {
1417
15- private SudokuSolver () {
16- // Utility class, prevent instantiation
17- }
18+ private SudokuSolver (){}
1819
1920 /**
20- * Solves the Sudoku puzzle using backtracking
21+ * Entry point to solve the Sudoku puzzle.
22+ * Performs a pre-validation check before starting the recursion.
2123 *
22- * @param board 9x9 Sudoku board with 0 representing empty cells
23- * @return true if puzzle is solved , false otherwise
24+ * @param board 2D array representing the Sudoku grid (0 for empty cells).
25+ * @return true if the board is solvable , false otherwise.
2426 */
2527 public static boolean solveSudoku (int [][] board ) {
26- if (board == null || board .length != GRID_SIZE ) {
28+ if (board == null || board .length !=9 || ! isBoardValid ( board ) ) {
2729 return false ;
2830 }
2931
30- for (int row = 0 ; row < GRID_SIZE ; row ++) {
31- if (board [row ].length != GRID_SIZE ) {
32- return false ;
33- }
34- }
35-
3632 return solve (board );
3733 }
3834
35+
3936 /**
40- * Recursive helper method to solve the Sudoku puzzle
37+ * Validates the initial state of the board to ensure no existing
38+ * numbers violate Sudoku rules.
4139 *
42- * @param board the Sudoku board
43- * @return true if solution is found, false otherwise
40+ * @param board The Sudoku grid.
41+ * @return true if the initial board configuration is valid.
4442 */
45- private static boolean solve (int [][] board ) {
46- for (int row = 0 ; row < GRID_SIZE ; row ++) {
47- for (int col = 0 ; col < GRID_SIZE ; col ++) {
48- if (board [row ][col ] == EMPTY_CELL ) {
49- for (int number = 1 ; number <= GRID_SIZE ; number ++) {
50- if (isValidPlacement (board , row , col , number )) {
51- board [row ][col ] = number ;
5243
53- if (solve (board )) {
54- return true ;
55- }
5644
57- // Backtrack
58- board [row ][col ] = EMPTY_CELL ;
59- }
45+ private static boolean isBoardValid (int [][] board ) {
46+ for (int i = 0 ; i < 9 ; i ++) {
47+ for (int j = 0 ; j < 9 ; j ++) {
48+ if (board [i ][j ] != 0 ) {
49+ int num = board [i ][j ];
50+ board [i ][j ] = 0 ; // Temporarily empty to validate
51+ if (!isValid (board , i , j , num )) {
52+ return false ;
6053 }
61- return false ;
54+
55+ board [i ][j ] = num ;
6256 }
6357 }
6458 }
59+
6560 return true ;
6661 }
6762
6863 /**
69- * Checks if placing a number at given position is valid
64+ * Checks if placing a number in a specific cell is legal.
7065 *
71- * @param board the Sudoku board
72- * @param row row index
73- * @param col column index
74- * @param number number to place (1-9)
75- * @return true if placement is valid, false otherwise
66+ * @param board The Sudoku grid.
67+ * @param row Row index.
68+ * @param col Column index.
69+ * @param num Number to place (1-9).
70+ * @return true if the placement is safe.
7671 */
77- private static boolean isValidPlacement (int [][] board , int row , int col , int number ) {
78- return !isNumberInRow (board , row , number ) && !isNumberInColumn (board , col , number ) && !isNumberInSubgrid (board , row , col , number );
79- }
72+ private static boolean isValid (int [][] board , int row , int col , int num ) {
73+ for (int i = 0 ; i < 9 ; i ++) {
74+ // Check row and column constraints
75+ if (board [i ][col ] == num || board [row ][i ] == num ) {
76+ return false ;
77+ }
78+ }
8079
81- /**
82- * Checks if number exists in the given row
83- *
84- * @param board the Sudoku board
85- * @param row row index
86- * @param number number to check
87- * @return true if number exists in row, false otherwise
88- */
89- private static boolean isNumberInRow (int [][] board , int row , int number ) {
90- for (int col = 0 ; col < GRID_SIZE ; col ++) {
91- if (board [row ][col ] == number ) {
92- return true ;
80+ // Check 3x3 sub-grid constraints
81+ int sr = (row / 3 ) * 3 ;
82+ int sc = (col / 3 ) * 3 ;
83+
84+ for (int i = sr ; i < sr + 3 ; i ++) {
85+ for (int j = sc ; j < sc + 3 ; j ++) {
86+ if (board [i ][j ] == num ) {
87+ return false ;
88+ }
9389 }
9490 }
95- return false ;
91+ return true ;
9692 }
9793
9894 /**
99- * Checks if number exists in the given column
95+ * Internal recursive helper that implements the backtracking logic.
10096 *
101- * @param board the Sudoku board
102- * @param col column index
103- * @param number number to check
104- * @return true if number exists in column, false otherwise
97+ * @param board The Sudoku grid being solved.
98+ * @return true if a solution is found.
10599 */
106- private static boolean isNumberInColumn (int [][] board , int col , int number ) {
107- for (int row = 0 ; row < GRID_SIZE ; row ++) {
108- if (board [row ][col ] == number ) {
109- return true ;
100+ private static boolean solve (int [][] board ) {
101+ for (int row = 0 ; row < 9 ; row ++) {
102+ for (int col = 0 ; col < 9 ; col ++) {
103+ if (board [row ][col ] == 0 ) {
104+ for (int num = 1 ; num <= 9 ; num ++) {
105+ if (isValid (board , row , col , num )) {
106+ board [row ][col ] = num ;
107+ if (solve (board )) {
108+ return true ;
109+ }
110+ board [row ][col ] = 0 ; // Backtrack
111+ }
112+ }
113+ return false ;
114+ }
110115 }
111116 }
112- return false ;
117+ return true ;
113118 }
114119
115120 /**
116- * Checks if number exists in the 3x3 subgrid
117- *
118- * @param board the Sudoku board
119- * @param row row index
120- * @param col column index
121- * @param number number to check
122- * @return true if number exists in subgrid, false otherwise
121+ * Demonstration of the solver.
123122 */
124- private static boolean isNumberInSubgrid (int [][] board , int row , int col , int number ) {
125- int subgridRowStart = row - row % SUBGRID_SIZE ;
126- int subgridColStart = col - col % SUBGRID_SIZE ;
127-
128- for (int i = subgridRowStart ; i < subgridRowStart + SUBGRID_SIZE ; i ++) {
129- for (int j = subgridColStart ; j < subgridColStart + SUBGRID_SIZE ; j ++) {
130- if (board [i ][j ] == number ) {
131- return true ;
132- }
133- }
123+ public static void main (String [] args ) {
124+
125+ int [][] board = {
126+ {5 , 3 , 0 , 0 , 7 , 0 , 0 , 0 , 0 },
127+ {6 , 0 , 0 , 1 , 9 , 5 , 0 , 0 , 0 },
128+ {0 , 9 , 8 , 0 , 0 , 0 , 0 , 6 , 0 },
129+ {8 , 0 , 0 , 0 , 6 , 0 , 0 , 0 , 3 },
130+ {4 , 0 , 0 , 8 , 0 , 3 , 0 , 0 , 1 },
131+ {7 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 6 },
132+ {0 , 6 , 0 , 0 , 0 , 0 , 2 , 8 , 0 },
133+ {0 , 0 , 0 , 4 , 1 , 9 , 0 , 0 , 5 },
134+ {0 , 0 , 0 , 0 , 8 , 0 , 0 , 7 , 9 }
135+ };
136+
137+ if (SudokuSolver .solveSudoku (board )) {
138+ printBoard (board );
139+ } else {
140+ System .out .println ("No solution exists." );
134141 }
135- return false ;
136142 }
137143
138144 /**
139- * Prints the Sudoku board
145+ * Helper method to print the board in a readable format.
140146 *
141- * @param board the Sudoku board
147+ * @param board The Sudoku grid.
142148 */
143- public static void printBoard (int [][] board ) {
144- for (int row = 0 ; row < GRID_SIZE ; row ++) {
145- if (row % SUBGRID_SIZE == 0 && row != 0 ) {
146- System .out .println ("-----------" );
147- }
148- for (int col = 0 ; col < GRID_SIZE ; col ++) {
149- if (col % SUBGRID_SIZE == 0 && col != 0 ) {
150- System .out .print ("|" );
151- }
152- System .out .print (board [row ][col ]);
149+ private static void printBoard (int [][] board ) {
150+ for (int i = 0 ; i < 9 ; i ++) {
151+ if (i % 3 == 0 && i != 0 ) System .out .println ("---------------------" );
152+ for (int j = 0 ; j < 9 ; j ++) {
153+ if (j % 3 == 0 && j != 0 ) System .out .print ("| " );
154+ System .out .print (board [i ][j ] + " " );
153155 }
154156 System .out .println ();
155157 }
156158 }
157- }
159+ }
0 commit comments