We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Backtracking

Now that we can check a position before committing to it, we don't have to build every board up front. Instead, we'll continuously build a single board, one row at a time:

  1. Try a column in the current row.
  2. If it's safe, place a queen there.
  3. Move on to the next row.
  4. If that path stops working, remove the queen and try the next column.

That "make a move, and undo it if it doesn't pan out" pattern is called backtracking.

Building and Undoing

Backtracking is a recursive search. We make a choice, explore everything that follows from it, and then undo it before trying the next option. The partial board still uses the same list representation:

board = [1, 3]

We've placed queens in rows 0 and 1, so the next recursive call handles row 2. If column 0 is safe, we place the queen:

board.append(0)

# [1, 3, 0]

Once we've explored every solution that starts with [1, 3, 0], we undo that choice:

board.pop()

# [1, 3]

Now we're free to try the next column for row 2.

Base Case

The search is done when we've placed a queen in every row. The moment row == n, the current board is a complete solution, and we save it and move on to the other options.

Because we keep mutating that same board list as the search goes, when we find a solution we have to save a copy of it:

solutions.append(board.copy())

This is a quirk of Python's memory model. If we appended board directly, every saved solution would point at the same list object, and they'd all change together as we kept going. Not what we want!

Assignment

Complete the solve_n_queens function, using recursive backtracking to build solutions one row at a time. The function accepts a board size n and returns all valid board arrangements.

With the brute-force approach, we couldn't even safely try n = 9. With backtracking, we can handle n = 10 without breaking a sweat in terms of memory or runtime. Nice.