I'm working on a DFS based solution to the N-queens problem.
I store the board state as an int[N] array representing the vertical placements of queens in each column (eg. placement of the queens diagonally down a 6x6 board would be state = { 0, 1, 2, 3, 4, 5 }), where -1 represents "no queen in this column".
My current algorithm for counting the queen attacks in a given state configuration has complexity of O(n^2):
function count_attacks(state)
attack_count = 0
for each column index c1
if state[c1] == -1 continue
for each column index c2 further along than c1
if state[c2] == -1 continue
// Lined up horizontally?
if state[c1] == state[c2] attack_count++
// Lined up diagonally?
else if (c2 - c1) == abs(state[c2] - state[c1]) attack_count++
// No need to check lined up vertically as impossible with this state representation
return attack_count;
The O(N^2) kills performance when solving for say N=500+.
Is it possible to do better than O(N^2) for counting attacks?
Define arrays
rows, columns, left_diagonals, right_diagonals
which count respectively the number of queens in the i
-th row, column, left diagonal (all x
and y
such that x-y=c
for some c
), right diagonal (all x
and y
such that x+y=c
for some c
). The algorithm would then be:
Intialize rows, columns, left_diagonals, right_diagonals with zero values
attacks = 0
for queen in queens
attacks += rows[queen.row];
attacks += columns[queen.column];
attacks += left_diagonals[queen.left_diagonal];
attacks += right_diagonals[queen.right_diagonal];
rows[queen.row]++;
columns[queen.column]++;
left_diagonals[queen.left_diagonal]++;
right_diagonals[queen.right_diagonal]++;
However, for solving the N
queen problem you don't need to check the number of attacks. You just need to check if an attack exists.
Also, if you are looking for a single solution of the problem there is a very efficient algorithm.