N-Queens
HardThe problem
Place n queens on an n × n chessboard so that no two queens attack each other (no two share a row, a column or a diagonal). Return every valid board, drawn as a list of strings where "Q" is a queen and "." is an empty square.
- Example 1Input: n = 4Output: [[".Q..", "...Q", "Q...", "..Q."], ["..Q.", "Q...", "...Q", ".Q.."]]
There are exactly two ways to place 4 queens safely on a 4 × 4 board.
- Example 2Input: n = 1Output: [["Q"]]
- 1 ≤ n ≤ 9
- The order of the boards does not matter
- If no board works return an empty list
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
Place one queen per row. How can you detect in O(1) that a column or diagonal is taken?
The idea
DFS row by row; keep sets for columns, r+c diagonals and r−c anti-diagonals. Place, recurse, remove. Record the board when all rows are filled.
Target: O(n!) time
Go function shape
func solveNQueens(n int) [][]stringReference solution
Tested with go test. Try it yourself first, then compare.
// SolveNQueens: all placements of n queens with no two attacking.
// One queen per row; three boolean sets make the "is it safe?" check O(1).
func SolveNQueens(n int) [][]string {
res := [][]string{}
cols := make([]bool, n)
diag := make([]bool, 2*n) // r+c
anti := make([]bool, 2*n) // r-c+n
queens := make([]int, n) // queens[r] = column of the queen in row r
var dfs func(r int)
dfs = func(r int) {
if r == n {
board := make([]string, n)
for i, c := range queens {
row := make([]byte, n)
for j := range row {
row[j] = '.'
}
row[c] = 'Q'
board[i] = string(row)
}
res = append(res, board)
return
}
for c := 0; c < n; c++ {
if cols[c] || diag[r+c] || anti[r-c+n] {
continue // prune: attacked square
}
cols[c], diag[r+c], anti[r-c+n] = true, true, true
queens[r] = c
dfs(r + 1)
cols[c], diag[r+c], anti[r-c+n] = false, false, false
}
}
dfs(0)
return res
}