Given an integer n, the task is to find the solution to the n-queens problem, where n queens are placed on an n*n chessboard such that no two queens can attack each other.
The N Queen is the problem of placing N chess queens on an N×N chessboard so that no two queens attack each other.
For example, the following is a solution for the 4 Queen problem.
Examples:
Input: 4
Output: [2, 4, 1, 3]
Explanation: [2, 4, 1, 3 ] and [3, 1, 4, 2] are the two possible solutions.
Input: 1
Output: [1]
Explanation: Only one queen can be placed in the single cell available.
[Naive Approach] - Using Backtracking - O(n*n!) Time and O(n*n) Space
The idea is to use backtracking to check all possible combinations of n queens in a chessboard of order n*n. To do so, first create an auxiliary matrix mat[][] of order n*n to mark the cellsoccupied by queens. Start from the first row and for each row place queen at different columns and check for clashes with other queens. To check for clashes, iterate through all the rows of current column and both the diagonals. If it is safe to place queen in current column, mark the cell occupied in matrix mat[][] and move to the next row. If at any row, there is no safe column to place the queen, backtrack to previous row and place the queen in other safe column and again check for the next row.
Below given is the recursive tree of the above approach:
Recursive tree for N Queen problemBelow given is the implementation:
C++
// C++ Program to solve the n-queens problem
#include <bits/stdc++.h>
using namespace std;
// Function to check if it is safe to place
// the queen at board[row][col]
int isSafe(vector<vector<int>>& mat,
int row, int col) {
int n = mat.size();
int i, j;
// Check this col on upper side
for (i = 0; i < row; i++)
if (mat[i][col])
return 0;
// Check upper diagonal on left side
for (i = row-1, j = col-1; i >= 0 &&
j >= 0; i--, j--)
if (mat[i][j])
return 0;
// Check upper diagonal on right side
for (i = row-1, j = col+1; j < n &&
i >= 0; i--, j++)
if (mat[i][j])
return 0;
return 1;
}
int placeQueens(int row, vector<vector<int>>& mat) {
int n = mat.size();
// base case: If all queens are placed
// then return true
if(row == n) return 1;
// Consider the row and try placing
// queen in all columns one by one
for(int i = 0; i < n; i++){
// Check if the queen can be placed
if(isSafe(mat, row, i)){
mat[row][i] = 1;
if(placeQueens(row + 1, mat))
return 1;
mat[row][i] = 0;
}
}
return 0;
}
// Function to find the solution
// to the N-Queens problem
vector<int> nQueen(int n) {
// Initialize the board
vector<vector<int>> mat(n, vector<int>(n, 0));
// If the solution exists
if(placeQueens(0, mat)){
// to store the columns of the queens
vector<int> ans;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(mat[i][j]){
ans.push_back(j + 1);
}
}
}
return ans;
}
else return {-1};
}
int main() {
int n = 4;
vector<int> ans = nQueen(n);
for(auto i: ans){
cout << i << " ";
}
return 0;
}
Java
// Java Program to solve the n-queens problem
import java.util.*;
class GfG {
// Function to check if it is safe to place
// the queen at board[row][col]
static boolean isSafe(int[][] mat,
int row, int col) {
int n = mat.length;
// Check this col on upper side
for (int i = 0; i < row; i++)
if (mat[i][col] == 1)
return false;
// Check upper diagonal on left side
for (int i = row - 1, j = col - 1;
i >= 0 && j >= 0; i--, j--)
if (mat[i][j] == 1)
return false;
// Check upper diagonal on right side
for (int i = row - 1, j = col + 1;
j < n && i >= 0; i--, j++)
if (mat[i][j] == 1)
return false;
return true;
}
static boolean placeQueens(int row, int[][] mat) {
int n = mat.length;
// base case: If all queens are placed
// then return true
if (row == n)
return true;
// Consider the row and try placing
// queen in all columns one by one
for (int i = 0; i < n; i++) {
// Check if the queen can be placed
if (isSafe(mat, row, i)) {
mat[row][i] = 1;
if (placeQueens(row + 1, mat))
return true;
mat[row][i] = 0;
}
}
return false;
}
// Function to find the solution
// to the N-Queens problem
static List<Integer> nQueen(int n) {
// Initialize the board
int[][] mat = new int[n][n];
// If the solution exists
if (placeQueens(0, mat)) {
// to store the columns of the queens
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) {
ans.add(j + 1);
}
}
}
return ans;
}
else
return Collections.singletonList(-1);
}
public static void main(String[] args) {
int n = 4;
List<Integer> ans = nQueen(n);
for (int i : ans) {
System.out.print(i + " ");
}
}
}
Python
# Python Program to solve the n-queens problem
# Function to check if it is safe to place
# the queen at board[row][col]
def isSafe(mat, row, col):
n = len(mat)
# Check this col on upper side
for i in range(row):
if mat[i][col]:
return False
# Check upper diagonal on left side
for i, j in zip(range(row - 1, -1, -1),
range(col - 1, -1, -1)):
if mat[i][j]:
return False
# Check upper diagonal on right side
for i, j in zip(range(row - 1, -1, -1),
range(col + 1, n)):
if mat[i][j]:
return False
return True
def placeQueens(row, mat):
n = len(mat)
# If all queens are placed
# then return true
if row == n:
return True
# Consider the row and try placing
# queen in all columns one by one
for i in range(n):
# Check if the queen can be placed
if isSafe(mat, row, i):
mat[row][i] = 1
if placeQueens(row + 1, mat):
return True
mat[row][i] = 0
return False
# Function to find the solution
# to the N-Queens problem
def nQueen(n):
# Initialize the board
mat = [[0 for _ in range(n)] for _ in range(n)]
# If the solution exists
if placeQueens(0, mat):
# to store the columns of the queens
ans = []
for i in range(n):
for j in range(n):
if mat[i][j]:
ans.append(j + 1)
return ans
else:
return [-1]
if __name__ == "__main__":
n = 4
ans = nQueen(n)
print(" ".join(map(str, ans)))
C#
// C# Program to solve the n-queens problem
using System;
using System.Collections.Generic;
class GfG {
// Function to check if it is safe to place
// the queen at board[row][col]
static bool IsSafe(int[,] mat,
int row, int col) {
int n = mat.GetLength(0);
// Check this col on upper side
for (int i = 0; i < row; i++)
if (mat[i, col] == 1)
return false;
// Check upper diagonal on left side
for (int i = row - 1, j = col - 1;
i >= 0 && j >= 0; i--, j--)
if (mat[i, j] == 1)
return false;
// Check upper diagonal on right side
for (int i = row - 1, j = col + 1;
j < n && i >= 0; i--, j++)
if (mat[i, j] == 1)
return false;
return true;
}
static bool PlaceQueens(int row, int[,] mat) {
int n = mat.GetLength(0);
// base case: If all queens are placed
// then return true
if (row == n)
return true;
// Consider the row and try placing
// queen in all columns one by one
for (int i = 0; i < n; i++) {
// Check if the queen can be placed
if (IsSafe(mat, row, i)) {
mat[row, i] = 1;
if (PlaceQueens(row + 1, mat))
return true;
mat[row, i] = 0;
}
}
return false;
}
// Function to find the solution
// to the N-Queens problem
public static List<int> NQueen(int n) {
// Initialize the board
int[,] mat = new int[n, n];
// If the solution exists
if (PlaceQueens(0, mat)) {
// to store the columns of the queens
List<int> ans = new List<int>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mat[i, j] == 1) {
ans.Add(j + 1);
}
}
}
return ans;
} else
return new List<int> { -1 };
}
static void Main(string[] args) {
int n = 4;
List<int> ans = NQueen(n);
Console.WriteLine(string.Join(" ", ans));
}
}
JavaScript
// JavaScript Program to solve the n-queens problem
// Function to check if it is safe to place
// the queen at board[row][col]
function isSafe(mat, row, col) {
const n = mat.length;
// Check this col on upper side
for (let i = 0; i < row; i++)
if (mat[i][col] === 1)
return false;
// Check upper diagonal on left side
for (let i = row - 1, j = col - 1;
i >= 0 && j >= 0; i--, j--)
if (mat[i][j] === 1)
return false;
// Check upper diagonal on right side
for (let i = row - 1, j = col + 1;
j < n && i >= 0; i--, j++)
if (mat[i][j] === 1)
return false;
return true;
}
function placeQueens(row, mat) {
const n = mat.length;
// base case: If all queens are placed
// then return true
if (row === n)
return true;
// Consider the row and try placing
// queen in all columns one by one
for (let i = 0; i < n; i++) {
// Check if the queen can be placed
if (isSafe(mat, row, i)) {
mat[row][i] = 1;
if (placeQueens(row + 1, mat))
return true;
mat[row][i] = 0;
}
}
return false;
}
// Function to find the solution
// to the N-Queens problem
function nQueen(n) {
// Initialize the board
const mat = Array.from({ length: n },
() => Array(n).fill(0));
// If the solution exists
if (placeQueens(0, mat)) {
// to store the columns of the queens
const ans = [];
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (mat[i][j] === 1) {
ans.push(j + 1);
}
}
}
return ans;
} else
return [-1];
}
const n = 4;
const ans = nQueen(n);
console.log(ans.join(" "));
Time Complexity: O(n*n!)
Auxiliary Space: O(n2)
[Optimized Approach] - O(n!) Time and O(n) Space
The above approach can be optimized by reducing the time required to check for clashes using isSafe() function. The idea is not to check every element in both the diagonals, instead use the property of diagonals:
- The sum of i and j is constant and unique for each right diagonal, where i is the row of elements and j is the column of elements.
- The difference between i and j is constant and unique for each left diagonal, where i and j are row and column of element respectively.
To do so, create three arrays cols[], rightDiagonal[] and leftDiagonal[] to mark the index of columns, left diagonal and right diagonals occupied by queens. For any cell, if all three arrays have value 0, we can place the queen at that cell.
Below is the implementation:
C++
// C++ Program to solve the n-queens problem
#include <bits/stdc++.h>
using namespace std;
int placeQueens(int i, vector<int> &cols, vector<int> &leftDiagonal,
vector<int> &rightDiagonal, vector<int> &cur) {
int n = cols.size();
// base case: If all queens are placed
// then return true
if(i == n) return 1;
// Consider the row and try placing
// queen in all columns one by one
for(int j = 0; j < n; j++){
// Check if the queen can be placed
if(cols[j] || rightDiagonal[i + j] ||
leftDiagonal[i - j + n - 1])
continue;
// mark the cell occupied
cols[j] = 1;
rightDiagonal[i+j] = 1;
leftDiagonal[i - j + n - 1] = 1;
cur.push_back(j+1);
if(placeQueens(i + 1, cols, leftDiagonal, rightDiagonal, cur))
return 1;
// remove the queen from current cell
cur.pop_back();
cols[j] = 0;
rightDiagonal[i+j] = 0;
leftDiagonal[i - j + n - 1] = 0;
}
return 0;
}
// Function to find the solution
// to the N-Queens problem
vector<int> nQueen(int n) {
// array to mark the occupied cells
vector<int> cols(n, 0);
vector<int> leftDiagonal(n*2, 0);
vector<int> rightDiagonal(n*2, 0);
vector<int> cur;
// If the solution exists
if(placeQueens(0, cols, leftDiagonal, rightDiagonal, cur))
return cur;
else return {-1};
}
int main() {
int n = 4;
vector<int> ans = nQueen(n);
for(auto i: ans){
cout << i << " ";
}
return 0;
}
Java
// Java Program to solve the n-queens problem
import java.util.*;
class GfG {
static boolean placeQueens(int i, int[] cols, int[] leftDiagonal,
int[] rightDiagonal, List<Integer> cur) {
int n = cols.length;
// base case: If all queens are placed
// then return true
if (i == n) return true;
// Consider the row and try placing
// queen in all columns one by one
for (int j = 0; j < n; j++) {
// Check if the queen can be placed
if (cols[j] == 1 || rightDiagonal[i + j] == 1 ||
leftDiagonal[i - j + n - 1] == 1)
continue;
// mark the cell occupied
cols[j] = 1;
rightDiagonal[i + j] = 1;
leftDiagonal[i - j + n - 1] = 1;
cur.add(j + 1);
if (placeQueens(i + 1, cols, leftDiagonal,
rightDiagonal, cur))
return true;
// remove the queen from current cell
cur.remove(cur.size() - 1);
cols[j] = 0;
rightDiagonal[i + j] = 0;
leftDiagonal[i - j + n - 1] = 0;
}
return false;
}
// Function to find the solution
// to the N-Queens problem
static List<Integer> nQueen(int n) {
// array to mark the occupied cells
int[] cols = new int[n];
int[] leftDiagonal = new int[n * 2];
int[] rightDiagonal = new int[n * 2];
List<Integer> cur = new ArrayList<>();
// If the solution exists
if (placeQueens(0, cols, leftDiagonal,
rightDiagonal, cur))
return cur;
else return Collections.singletonList(-1);
}
public static void main(String[] args) {
int n = 4;
List<Integer> ans = nQueen(n);
for (int i : ans) {
System.out.print(i + " ");
}
}
}
Python
# Python Program to solve the n-queens problem
def placeQueens(i, cols, leftDiagonal, rightDiagonal, cur):
n = len(cols)
# base case: If all queens are placed
# then return true
if i == n:
return True
# Consider the row and try placing
# queen in all columns one by one
for j in range(n):
# Check if the queen can be placed
if cols[j] or rightDiagonal[i + j] or leftDiagonal[i - j + n - 1]:
continue
# mark the cell occupied
cols[j] = 1
rightDiagonal[i + j] = 1
leftDiagonal[i - j + n - 1] = 1
cur.append(j + 1)
if placeQueens(i + 1, cols, leftDiagonal, rightDiagonal, cur):
return True
# remove the queen from current cell
cur.pop()
cols[j] = 0
rightDiagonal[i + j] = 0
leftDiagonal[i - j + n - 1] = 0
return False
# Function to find the solution
# to the N-Queens problem
def nQueen(n):
# array to mark the occupied cells
cols = [0] * n
leftDiagonal = [0] * (n * 2)
rightDiagonal = [0] * (n * 2)
cur = []
# If the solution exists
if placeQueens(0, cols, leftDiagonal, rightDiagonal, cur):
return cur
else:
return [-1]
if __name__ == "__main__":
n = 4
ans = nQueen(n)
print(" ".join(map(str, ans)))
C#
// C# Program to solve the n-queens problem
using System;
using System.Collections.Generic;
class GfG {
static bool PlaceQueens(int i, int[] cols, int[] leftDiagonal,
int[] rightDiagonal, List<int> cur) {
int n = cols.Length;
// base case: If all queens are placed
// then return true
if (i == n) return true;
// Consider the row and try placing
// queen in all columns one by one
for (int j = 0; j < n; j++) {
// Check if the queen can be placed
if (cols[j] == 1 || rightDiagonal[i + j] == 1 ||
leftDiagonal[i - j + n - 1] == 1)
continue;
// mark the cell occupied
cols[j] = 1;
rightDiagonal[i + j] = 1;
leftDiagonal[i - j + n - 1] = 1;
cur.Add(j + 1);
if (PlaceQueens(i + 1, cols, leftDiagonal,
rightDiagonal, cur))
return true;
// remove the queen from current cell
cur.RemoveAt(cur.Count - 1);
cols[j] = 0;
rightDiagonal[i + j] = 0;
leftDiagonal[i - j + n - 1] = 0;
}
return false;
}
// Function to find the solution
// to the N-Queens problem
static List<int> NQueen(int n) {
// array to mark the occupied cells
int[] cols = new int[n];
int[] leftDiagonal = new int[n * 2];
int[] rightDiagonal = new int[n * 2];
List<int> cur = new List<int>();
// If the solution exists
if (PlaceQueens(0, cols, leftDiagonal,
rightDiagonal, cur))
return cur;
else return new List<int> { -1 };
}
static void Main(string[] args) {
int n = 4;
List<int> ans = NQueen(n);
foreach (int i in ans) {
Console.Write(i + " ");
}
}
}
JavaScript
// JavaScript Program to solve the n-queens problem
function placeQueens(i, cols, leftDiagonal, rightDiagonal, cur) {
const n = cols.length;
// base case: If all queens are placed
// then return true
if (i === n) return true;
// Consider the row and try placing
// queen in all columns one by one
for (let j = 0; j < n; j++) {
// Check if the queen can be placed
if (cols[j] || rightDiagonal[i + j] ||
leftDiagonal[i - j + n - 1])
continue;
// mark the cell occupied
cols[j] = 1;
rightDiagonal[i + j] = 1;
leftDiagonal[i - j + n - 1] = 1;
cur.push(j + 1);
if (placeQueens(i + 1, cols, leftDiagonal,
rightDiagonal, cur))
return true;
// remove the queen from current cell
cur.pop();
cols[j] = 0;
rightDiagonal[i + j] = 0;
leftDiagonal[i - j + n - 1] = 0;
}
return false;
}
// Function to find the solution
// to the N-Queens problem
function nQueen(n) {
// array to mark the occupied cells
const cols = new Array(n).fill(0);
const leftDiagonal = new Array(n * 2).fill(0);
const rightDiagonal = new Array(n * 2).fill(0);
const cur = [];
// If the solution exists
if (placeQueens(0, cols, leftDiagonal,
rightDiagonal, cur))
return cur;
else return [-1];
}
const n = 4;
const ans = nQueen(n);
console.log(ans.join(" "));
Time Complexity: O(n!)
Auxiliary Space: O(n)
Related Articles:
Similar Reads
N Queen Problem Given an integer n, the task is to find the solution to the n-queens problem, where n queens are placed on an n*n chessboard such that no two queens can attack each other. The N Queen is the problem of placing N chess queens on an NÃN chessboard so that no two queens attack each other. For example,
15+ min read
N-Queen in Different languages
4 Queens Problem The 4 Queens Problem consists in placing four queens on a 4 x 4 chessboard so that no two queens attack each other. That is, no two queens are allowed to be placed on the same row, the same column or the same diagonal. We are going to look for the solution for n=4 on a 4 x 4 chessboard in this artic
15 min read
8 queen problem Given an 8x8 chessboard, the task is to place 8 queens on the board such that no 2 queens threaten each other. Return a matrix of size 8x8, where 1 represents queen and 0 represents an empty position. Approach:The idea is to use backtracking to place the queens one by one on the board. Starting from
9 min read
N Queen Problem using Branch And Bound The N queens puzzle is the problem of placing N chess queens on an NÃN chessboard so that no two queens threaten each other. Thus, a solution requires that no two queens share the same row, column, or diagonal. The backtracking Algorithm for N-Queen is already discussed here. In a backtracking solut
15+ min read
N Queen in O(n) space Given an integer n, the task is to find the solution to the n-queens problem, where n queens are placed on an n*n chessboard such that no two queens can attack each other.The N Queen is the problem of placing N chess queens on an NÃN chessboard so that no two queens attack each other.For example, th
7 min read
Printing all solutions in N-Queen Problem Given an integer n, the task is to find all distinct solutions to the n-queens problem, where n queens are placed on an n * n chessboard such that no two queens can attack each other. Note: Each solution is a unique configuration of n queens, represented as a permutation of [1,2,3,....,n]. The numbe
15+ min read
Minimum queens required to cover all the squares of a chess board Given the dimension of a chess board (N x M), determine the minimum number of queens required to cover all the squares of the board. A queen can attack any square along its row, column or diagonals. Examples: Input : N = 8, M = 8Output : 5Layout : Q X X X X X X X X X Q X X X X X X X X X Q X X X X Q
14 min read
Number of cells a queen can move with obstacles on the chessboard Consider a N X N chessboard with a Queen and K obstacles. The Queen cannot pass through obstacles. Given the position (x, y) of Queen, the task is to find the number of cells the queen can move. Examples: Input : N = 8, x = 4, y = 4, K = 0 Output : 27 Input : N = 8, x = 4, y = 4, K = 1, kx1 = 3, ky1
15+ min read
N-Queen Problem | Local Search using Hill climbing with random neighbour The N Queen is the problem of placing N chess queens on an NÃN chessboard so that no two queens attack each other. For example, the following is a solution for 8 Queen problem. Input: N = 4 Output: 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 Explanation: The Position of queens are: 1 - {1, 2} 2 - {2, 4} 3 - {3,
15+ min read