22
33import java .util .ArrayList ;
44import java .util .List ;
5+ import java .util .HashSet ;
6+ import java .util .Set ;
57
68/**
79 * Problem statement: Given a N x N chess board. Return all arrangements in
3234 * queen is not placed safely. If there is no such way then return an empty list
3335 * as solution
3436 */
37+
38+ /*
39+ * Time Complexity: O(N!)
40+ * space Complexity: O(N)
41+ */
3542public final class NQueens {
43+
44+ // Store occupied rows for constant time safety check
45+ private static final Set <Integer > occupiedRows = new HashSet <>();
46+
47+ // Store occupied main diagonals (row - column)
48+ private static final Set <Integer > occupiedDiagonals = new HashSet <>();
49+
50+ // Store occupied anti-diagonals (row + columns)
51+ private static final Set <Integer > occupiedAntiDiagonals = new HashSet <>();
52+
3653 private NQueens () {
3754 }
3855
@@ -43,10 +60,11 @@ public static List<List<String>> getNQueensArrangements(int queens) {
4360 }
4461
4562 public static void placeQueens (final int queens ) {
46- List <List <String >> arrangements = new ArrayList <List < String > >();
63+ List <List <String >> arrangements = new ArrayList <>();
4764 getSolution (queens , arrangements , new int [queens ], 0 );
4865 if (arrangements .isEmpty ()) {
49- System .out .println ("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens );
66+ System .out .println (
67+ "There is no way to place " + queens + " queens on board of size " + queens + "x" + queens );
5068 } else {
5169 System .out .println ("Arrangement for placing " + queens + " queens" );
5270 }
@@ -59,15 +77,15 @@ public static void placeQueens(final int queens) {
5977 /**
6078 * This is backtracking function which tries to place queen recursively
6179 *
62- * @param boardSize: size of chess board
63- * @param solutions: this holds all possible arrangements
64- * @param columns: columns[i] = rowId where queen is placed in ith column.
80+ * @param boardSize: size of chess board
81+ * @param solutions: this holds all possible arrangements
82+ * @param columns: columns[i] = rowId where queen is placed in ith column.
6583 * @param columnIndex: This is the column in which queen is being placed
6684 */
6785 private static void getSolution (int boardSize , List <List <String >> solutions , int [] columns , int columnIndex ) {
6886 if (columnIndex == boardSize ) {
6987 // this means that all queens have been placed
70- List <String > sol = new ArrayList <String >();
88+ List <String > sol = new ArrayList <>();
7189 for (int i = 0 ; i < boardSize ; i ++) {
7290 StringBuilder sb = new StringBuilder ();
7391 for (int j = 0 ; j < boardSize ; j ++) {
@@ -82,30 +100,28 @@ private static void getSolution(int boardSize, List<List<String>> solutions, int
82100 // This loop tries to place queen in a row one by one
83101 for (int rowIndex = 0 ; rowIndex < boardSize ; rowIndex ++) {
84102 columns [columnIndex ] = rowIndex ;
85- if (isPlacedCorrectly (columns , rowIndex , columnIndex )) {
86- // If queen is placed successfully at rowIndex in column=columnIndex then try
87- // placing queen in next column
88- getSolution (boardSize , solutions , columns , columnIndex + 1 );
89- }
90- }
91- }
92103
93- /**
94- * This function checks if queen can be placed at row = rowIndex in column =
95- * columnIndex safely
96- *
97- * @param columns: columns[i] = rowId where queen is placed in ith column.
98- * @param rowIndex: row in which queen has to be placed
99- * @param columnIndex: column in which queen is being placed
100- * @return true: if queen can be placed safely false: otherwise
101- */
102- private static boolean isPlacedCorrectly (int [] columns , int rowIndex , int columnIndex ) {
103- for (int i = 0 ; i < columnIndex ; i ++) {
104- int diff = Math .abs (columns [i ] - rowIndex );
105- if (diff == 0 || columnIndex - i == diff ) {
106- return false ;
104+ // Skip current position if row or diagonal is already occupied
105+ if (occupiedRows .contains (rowIndex )
106+ || occupiedDiagonals .contains (rowIndex - columnIndex )
107+ || occupiedAntiDiagonals .contains (rowIndex + columnIndex )) {
108+ continue ;
107109 }
110+
111+ // Mark current row and diagonal as occupied
112+ occupiedRows .add (rowIndex );
113+ occupiedDiagonals .add (rowIndex - columnIndex );
114+ occupiedAntiDiagonals .add (rowIndex + columnIndex );
115+
116+ // Move to the next column after placing current queen
117+ getSolution (boardSize , solutions , columns , columnIndex + 1 );
118+
119+ // Backtrack by removing current queen
120+
121+ occupiedRows .remove (rowIndex );
122+ occupiedDiagonals .remove (rowIndex - columnIndex );
123+ occupiedAntiDiagonals .remove (rowIndex + columnIndex );
108124 }
109- return true ;
110125 }
126+
111127}
0 commit comments