Problem Statement in English

You’ve to place n queens on an n x n chessboard such that no two queens attack each other.


Approach

This is a classic backtracking problem, and it’s more of an implementation problem.

We use backtracking for the actual placement paired with $O(1)$ checks to see if the placement is valid.

For the check we use three sets to keep track of the columns and diagonals that are already occupied by queens. For the positive diagonals shaped like / we use r + c, and for the negative diagonals shaped like \ we use r - c.

The reason we’re able to remove a queen from a diagonal with a set rather than a hashmap is that when we place a queen and recurse forward it’s guaranteed that there were no queens on that diagonal before, and when we backtrack we remove the queen from that diagonal, so it’s guaranteed that there are no queens on that diagonal after we remove it. Hence, a set suffices.

And we are done!


Solution in Python


class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        res = []
        cols = set()
        pos_diag = set()  # r + c
        neg_diag = set()  # r - c

        board = [["."] * n for _ in range(n)]

        def dfs(r):
            if r == n:
                res.append(["".join(row) for row in board])
                return

            for c in range(n):
                if c in cols or (r + c) in pos_diag or (r - c) in neg_diag:
                    continue

                cols.add(c)
                pos_diag.add(r + c)
                neg_diag.add(r - c)
                board[r][c] = "Q"

                dfs(r + 1)

                cols.remove(c)
                pos_diag.remove(r + c)
                neg_diag.remove(r - c)
                board[r][c] = "."

        dfs(0)
        return res

Complexity

  • Time: $O(n!)$
    Since we are trying to place the queens in all possible ways.

  • Space: $O(n^2)$
    Since we are using a 2D array to store the board state.


And we are done.