-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathn_queens.rs
54 lines (46 loc) · 1.76 KB
/
n_queens.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
pub fn n_queens(n: i32) -> i32 {
let mut res = 0;
let mut diagonals_set = std::collections::HashSet::new();
let mut anti_diagonals_set = std::collections::HashSet::new();
let mut cols_set = std::collections::HashSet::new();
dfs(0, &mut diagonals_set, &mut anti_diagonals_set, &mut cols_set, n, &mut res);
res
}
fn dfs(
r: i32,
diagonals_set: &mut std::collections::HashSet<i32>,
anti_diagonals_set: &mut std::collections::HashSet<i32>,
cols_set: &mut std::collections::HashSet<i32>,
n: i32,
res: &mut i32
) {
// Termination condition: If we have reached the end of the rows,
// we've placed all 'n' queens.
if r == n {
*res += 1;
return;
}
for c in 0..n {
let curr_diagonal = r - c;
let curr_anti_diagonal = r + c;
// If there are queens on the current column, diagonal or
// anti-diagonal, skip this square.
if cols_set.contains(&c) ||
diagonals_set.contains(&curr_diagonal) ||
anti_diagonals_set.contains(&curr_anti_diagonal) {
continue;
}
// Place the queen by marking the current column, diagonal, and
// anti-diagonal as occupied.
cols_set.insert(c);
diagonals_set.insert(curr_diagonal);
anti_diagonals_set.insert(curr_anti_diagonal);
// Recursively move to the next row to continue placing queens.
dfs(r + 1, diagonals_set, anti_diagonals_set, cols_set, n, res);
// Backtrack by removing the current column, diagonal, and
// anti-diagonal from the hash sets.
cols_set.remove(&c);
diagonals_set.remove(&curr_diagonal);
anti_diagonals_set.remove(&curr_anti_diagonal);
}
}