Problem

The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.

Given an integer n, return the number of distinct solutions to the n-queens puzzle.

Examples

Example 1:

Input: n = 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown.

Example 2:

Input: n = 1
Output: 1

Solution

We have already seen N-Queens Problem. We can use backtracking similar to that, and may be this problem is bit easier.

Method 1 - Backtracking Using O(N^2) Space Matrix

This is similar to the problem we had solved with O(n^2) matrix in N-Queens Problem. But in dfs, we will not pass a list and also return a count instead of adding solution to list.

Code

Java
public int totalNQueens(int n) {
	char[][] board = new char[n][n];
	for (char[] row: board) {
		Arrays.fill(row, '.');
	}
	return dfs(board, 0);
}

private int dfs(char[][] board, int colIndex) {
	if (colIndex == board.length) {
		return 1;
	}
	int count = 0;
	for (int i = 0; i<board.length; i++) {
		if (isSafe(board, i, colIndex)) {
			board[i][colIndex] = 'Q';
			count += dfs(board, colIndex + 1);
			board[i][colIndex] = '.';
		}
	}
	return count;
}

private boolean isSafe(char[][] board, int x, int y) {
	for (int i = 0; i<board.length; i++) {
		for (int j = 0; j<y; j++) {
			if (board[i][j] == 'Q' && (x + j == y + i || x + y == i + j || x == i)) {
				return false;
			}
		}
	}

	return true;
}

Method 2 - Backtracking Using O(N) Space Row

Again this is similar to Backtracking Using O(N) Space Row in N-Queens Problem.

Code

Java
public int totalNQueens(int n) {
	return dfs(0, new int[n]);
}

public int dfs(int cur, int[] row) {
	if (cur == row.length) {
		return 1;
	}
	int count = 0;
	for (int i = 0; i < row.length; i++) {
		boolean ok = true;
		row[cur] = i;
		for (int j = 0; j < cur; j++) {
			if (row[cur] == row[j] || row[cur] - row[j] == cur - j || row[cur] - row[j] == j - cur) {
				ok = false;
				break;
			}
		}
		if (ok) {
			count += dfs(cur + 1, row);
		}
	}
	return count;
}

Complexity

  • ⏰ Time complexity: O(N! * N)
  • 🧺 Space complexity: O(N^2)

Method 3 - Backtracking Using Sets for Row and Diagonals

Code

Java
public int totalNQueens(int n) {
    int[] res = new int[1];
    helper(res,n,0);
    return res[0];
}
public void helper(int[] res, int n, int row){
    if(row==n){
        res[0]++;
    }
    else{
        for(int i=0; i<n; i++){
            if(col.contains(i) || diag1.contains(i+row) || diag2.contains(row-i)) continue;
            else{
                col.add(i);
                diag1.add(i+row);
                diag2.add(row-i);
                helper(res,n,row+1);
                col.remove(i);
                diag1.remove(i+row);
                diag2.remove(row-i);
            }
        }
    }
}

Method 4 - Backtracking Using Boolean Arrays for Col and Diagonals

Code

Java
public class Solution {
    int count = 0;
    public int totalNQueens(int n) {
        boolean[] cols = new boolean[n];     // columns   |
        boolean[] d1 = new boolean[2 * n];   // diagonals \
        boolean[] d2 = new boolean[2 * n];   // diagonals /
        backtracking(0, cols, d1, d2, n);
        return count;
    }

    public void backtracking(int row, boolean[] cols, boolean[] d1, boolean []d2, int n) {
        if(row == n) count++;

        for(int col = 0; col < n; col++) {
            int id1 = col - row + n;
            int id2 = col + row;
            if(cols[col] || d1[id1] || d2[id2]) continue;

            cols[col] = true; d1[id1] = true; d2[id2] = true;
            backtracking(row + 1, cols, d1, d2, n);
            cols[col] = false; d1[id1] = false; d2[id2] = false;
        }
    }
}