Backtracking (N-Queens and Subset Sum)

Build a solution one choice at a time and undo choices that cannot work: the state-space tree, pruning, N-Queens, subset sum, permutations and graph colouring.

Backtracking searches for solutions by making one choice at a time. As soon as a partial solution cannot possibly lead to a valid answer, it undoes the last choice (backtracks) and tries the next option. It is a depth-first search of the state-space tree of all choices, with branches cut off early (pruning).

The pattern

solve(partial)partial is a complete solution?YesNoRecord itFor each choice that keeps partial validMake the choice (choose)solve(extended partial) (explore)Undo the choice (unchoose)Returngateshala.com
The backtracking pattern

Every backtracking program has the same three steps: choose, explore, unchoose. Pruning is what makes it faster than trying everything blindly.

N-Queens

Place n queens on an n × n board so that no two attack each other (same row, column or diagonal). Put one queen per row; in row r, try each column c that is not attacked:

  • Same column: col[i] = c.
  • Same diagonal: |col[i] − c| = r − i.
startQ0 at 0Q1 at 2dead endQ1 at 3Q2 at 1dead endQ0 at 1Q1 at 3Q2 at 0Q3 at 2solutiongateshala.com
Part of the state-space tree for 4-Queens (row 0, column chosen at each level)

The 4-Queens problem has 2 solutions, 6-Queens has 4 and 8-Queens has 92.

Subset sum

Find subsets of a set that add up to a target. At each element, branch on take or skip, and prune when the remaining target goes negative.

The code

import java.util.*;

public class Main {
    static int n, count;
    static int[] col;                       // col[r] = column of the queen in row r

    static boolean safe(int r, int c) {
        for (int i = 0; i < r; i++)
            if (col[i] == c || Math.abs(col[i] - c) == r - i) return false;
        return true;
    }

    static void place(int r, boolean print) {
        if (r == n) {                       // all rows filled: a solution
            count++;
            if (print) System.out.println("solution: " + Arrays.toString(col));
            return;
        }
        for (int c = 0; c < n; c++) {
            if (safe(r, c)) {
                col[r] = c;                 // choose
                place(r + 1, print);        // explore
            }                               // undo is implicit: col[r] is overwritten
        }
    }

    static void subsets(int[] a, int i, int target, List<Integer> chosen) {
        if (target == 0) { System.out.println("sum found: " + chosen); return; }
        if (i == a.length || target < 0) return;   // prune
        chosen.add(a[i]);
        subsets(a, i + 1, target - a[i], chosen);  // take a[i]
        chosen.remove(chosen.size() - 1);
        subsets(a, i + 1, target, chosen);         // skip a[i]
    }

    public static void main(String[] args) {
        n = 4; col = new int[n]; count = 0;
        place(0, true);
        for (int size : new int[]{6, 8}) {
            n = size; col = new int[n]; count = 0;
            place(0, false);
            System.out.println(size + "-queens solutions: " + count);
        }
        subsets(new int[]{3, 4, 5, 2}, 0, 9, new ArrayList<>());
    }
}
Output
solution: [1, 3, 0, 2]
solution: [2, 0, 3, 1]
6-queens solutions: 4
8-queens solutions: 92
sum found: [3, 4, 2]
sum found: [4, 5]

Other backtracking problems

  • Permutations of n items: n! leaves; swap an item into place, recurse, swap back.
  • Graph colouring with m colours: give each vertex a colour different from its coloured neighbours.
  • Hamiltonian cycle, Sudoku, word search in a grid, rat in a maze.

Backtracking is still exponential in the worst case; pruning only reduces how much of the tree is explored. Branch and bound adds a bound on the best possible answer from a node, to prune optimisation problems.

GATE-style practice questions

GATE-styleNAT · numerical answer

How many solutions does the 5-Queens problem have?

Show answer and explanationAnswer: 10

Backtracking over one queen per row finds 10 placements for a 5 × 5 board.

GATE-styleNAT · numerical answer

How many subsets of {1, 2, 3, 4, 5} have a sum of exactly 7?

Show answer and explanationAnswer: 3

{2, 5}, {3, 4} and {1, 2, 4}.

GATE-styleMCQ · one correct answer

Backtracking explores the state-space tree in which order?

Show answer and explanationAnswer: B

It follows one branch down until it finds a solution or a dead end, then backs up: a depth-first search with pruning.

GATE-styleNAT · numerical answer

How many leaves does the full state-space tree for generating all permutations of 5 distinct items have?

Show answer and explanationAnswer: 120

There are 5! = 120 permutations, one per leaf.