Skip to content

Commit a497bfe

Browse files
Merge branch 'master' into add-wavelet-tree
2 parents 04803ba + 54341c1 commit a497bfe

1 file changed

Lines changed: 44 additions & 28 deletions

File tree

src/main/java/com/thealgorithms/backtracking/NQueens.java

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.thealgorithms.backtracking;
22

33
import java.util.ArrayList;
4+
import java.util.HashSet;
45
import java.util.List;
6+
import java.util.Set;
57

68
/**
79
* Problem statement: Given a N x N chess board. Return all arrangements in
@@ -32,7 +34,22 @@
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+
*/
3542
public final class NQueens {
43+
44+
// Store occupied rows for constant time safety check
45+
private static final Set<Integer> OCROWS = new HashSet<>();
46+
47+
// Store occupied main diagonals (row - column)
48+
private static final Set<Integer> OCDIAG = new HashSet<>();
49+
50+
// Store occupied anti-diagonals (row + columns)
51+
private static final Set<Integer> OCANTIDIAG = new HashSet<>();
52+
3653
private NQueens() {
3754
}
3855

@@ -43,10 +60,10 @@ 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(" no way to place " + queens + " queens on board of size " + queens + "x" + queens);
5067
} else {
5168
System.out.println("Arrangement for placing " + queens + " queens");
5269
}
@@ -59,15 +76,15 @@ public static void placeQueens(final int queens) {
5976
/**
6077
* This is backtracking function which tries to place queen recursively
6178
*
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.
79+
* @param boardSize: size of chess board
80+
* @param solutions: this holds all possible arrangements
81+
* @param columns: columns[i] = rowId where queen is placed in ith column.
6582
* @param columnIndex: This is the column in which queen is being placed
6683
*/
6784
private static void getSolution(int boardSize, List<List<String>> solutions, int[] columns, int columnIndex) {
6885
if (columnIndex == boardSize) {
6986
// this means that all queens have been placed
70-
List<String> sol = new ArrayList<String>();
87+
List<String> sol = new ArrayList<>();
7188
for (int i = 0; i < boardSize; i++) {
7289
StringBuilder sb = new StringBuilder();
7390
for (int j = 0; j < boardSize; j++) {
@@ -82,30 +99,29 @@ private static void getSolution(int boardSize, List<List<String>> solutions, int
8299
// This loop tries to place queen in a row one by one
83100
for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
84101
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-
}
92102

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;
103+
// Skip current position if row or diagonal is already occupied
104+
boolean isROp = OCROWS.contains(rowIndex);
105+
106+
boolean isDOp = OCDIAG.contains(rowIndex - columnIndex) || OCANTIDIAG.contains(rowIndex + columnIndex);
107+
108+
if (isROp || isDOp) {
109+
continue;
107110
}
111+
112+
// Mark current row and diagonal as occupied
113+
OCROWS.add(rowIndex);
114+
OCDIAG.add(rowIndex - columnIndex);
115+
OCANTIDIAG.add(rowIndex + columnIndex);
116+
117+
// Move to the next column after placing current queen
118+
getSolution(boardSize, solutions, columns, columnIndex + 1);
119+
120+
// Backtrack by removing current queen
121+
122+
OCROWS.remove(rowIndex);
123+
OCDIAG.remove(rowIndex - columnIndex);
124+
OCANTIDIAG.remove(rowIndex + columnIndex);
108125
}
109-
return true;
110126
}
111127
}

0 commit comments

Comments
 (0)