Place n queens on an n×n chessboard so that no two attack each other (same row, column, or diagonal). Return all valid arrangements, where each solution shows the column position of the queen in each row.
Examples:
Input: n = 4 Output: [[2, 4, 1, 3], [3, 1, 4, 2]] Explanation: We mainly print column numbers (from first to last row) of every possible configuration.
Input: n = 3 Output: [] Explanation: There are no possible solutions for n = 3
Use backtracking to place queens row by row, checking if each position is safe. If safe, place the queen and move to the next row; otherwise, backtrack and try another position. Store the solution when all queens are placed.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to check if it is safe to placeintisSafe(vector<vector<int>>&mat,introw,intcol){intn=mat.size();inti,j;// Check this col on upper sidefor(i=0;i<row;i++)if(mat[i][col])return0;// Check upper diagonal on left sidefor(i=row-1,j=col-1;i>=0&&j>=0;i--,j--)if(mat[i][j])return0;// Check upper diagonal on right sidefor(i=row-1,j=col+1;j<n&&i>=0;i--,j++)if(mat[i][j])return0;return1;}// Recursive function to place queensvoidplaceQueens(introw,vector<vector<int>>&mat,vector<vector<int>>&result){intn=mat.size();// base case: If all queens are placedif(row==n){// store current solutionvector<int>ans;for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i][j]){ans.push_back(j+1);}}}result.push_back(ans);return;}// Consider the row and try placing// queen in all columns one by onefor(inti=0;i<n;i++){// Check if the queen can be placedif(isSafe(mat,row,i)){mat[row][i]=1;placeQueens(row+1,mat,result);// backtrackmat[row][i]=0;}}}// Function to find all solutionsvector<vector<int>>nQueen(intn){// Initialize the boardvector<vector<int>>mat(n,vector<int>(n,0));vector<vector<int>>result;// Place queensplaceQueens(0,mat,result);returnresult;}intmain(){intn=4;vector<vector<int>>result=nQueen(n);for(auto&ans:result){for(autoi:ans){cout<<i<<" ";}cout<<endl;}return0;}
Java
importjava.util.ArrayList;classGFG{// Function to check if it is safe to placestaticintisSafe(int[][]mat,introw,intcol){intn=mat.length;inti,j;// Check this col on upper sidefor(i=0;i<row;i++)if(mat[i][col]==1)return0;// Check upper diagonal on left sidefor(i=row-1,j=col-1;i>=0&&j>=0;i--,j--)if(mat[i][j]==1)return0;// Check upper diagonal on right sidefor(i=row-1,j=col+1;j<n&&i>=0;i--,j++)if(mat[i][j]==1)return0;return1;}// Recursive function to place queensstaticvoidplaceQueens(introw,int[][]mat,ArrayList<ArrayList<Integer>>result){intn=mat.length;// base case: If all queens are placedif(row==n){// store current solutionArrayList<Integer>ans=newArrayList<>();for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i][j]==1){ans.add(j+1);}}}result.add(ans);return;}// Consider the row and try placing// queen in all columns one by onefor(inti=0;i<n;i++){// Check if the queen can be placedif(isSafe(mat,row,i)==1){mat[row][i]=1;placeQueens(row+1,mat,result);// backtrackmat[row][i]=0;}}}// Function to find all solutionsstaticArrayList<ArrayList<Integer>>nQueen(intn){// Initialize the boardint[][]mat=newint[n][n];ArrayList<ArrayList<Integer>>result=newArrayList<>();// Place queensplaceQueens(0,mat,result);returnresult;}publicstaticvoidmain(String[]args){intn=4;ArrayList<ArrayList<Integer>>result=nQueen(n);for(ArrayList<Integer>ans:result){for(inti:ans){System.out.print(i+" ");}System.out.println();}}}
Python
defisSafe(mat,row,col):n=len(mat)# Check this col on upper sideforiinrange(row):ifmat[i][col]:return0# Check upper diagonal on left sidei,j=row-1,col-1whilei>=0andj>=0:ifmat[i][j]:return0i-=1j-=1# Check upper diagonal on right sidei,j=row-1,col+1whilei>=0andj<n:ifmat[i][j]:return0i-=1j+=1return1# Recursive function to place queensdefplaceQueens(row,mat,result):n=len(mat)# base case: If all queens are placedifrow==n:# store current solutionans=[]foriinrange(n):forjinrange(n):ifmat[i][j]:ans.append(j+1)result.append(ans)return# Consider the row and try placing# queen in all columns one by oneforiinrange(n):# Check if the queen can be placedifisSafe(mat,row,i):mat[row][i]=1placeQueens(row+1,mat,result)# backtrackmat[row][i]=0# Function to find all solutionsdefnQueen(n):# Initialize the boardmat=[[0]*nfor_inrange(n)]result=[]# Place queensplaceQueens(0,mat,result)returnresultif__name__=="__main__":n=4result=nQueen(n)foransinresult:print(" ".join(map(str,ans)))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to check if it is safe to placestaticintisSafe(int[,]mat,introw,intcol){intn=mat.GetLength(0);inti,j;// Check this col on upper sidefor(i=0;i<row;i++)if(mat[i,col]==1)return0;// Check upper diagonal on left sidefor(i=row-1,j=col-1;i>=0&&j>=0;i--,j--)if(mat[i,j]==1)return0;// Check upper diagonal on right sidefor(i=row-1,j=col+1;j<n&&i>=0;i--,j++)if(mat[i,j]==1)return0;return1;}// Recursive function to place queensstaticvoidplaceQueens(introw,int[,]mat,List<List<int>>result){intn=mat.GetLength(0);// base case: If all queens are placedif(row==n){// store current solutionList<int>ans=newList<int>();for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i,j]==1){ans.Add(j+1);}}}result.Add(ans);return;}// Consider the row and try placing// queen in all columns one by onefor(inti=0;i<n;i++){// Check if the queen can be placedif(isSafe(mat,row,i)==1){mat[row,i]=1;placeQueens(row+1,mat,result);// backtrackmat[row,i]=0;}}}// Function to find all solutionsstaticList<List<int>>nQueen(intn){// Initialize the boardint[,]mat=newint[n,n];List<List<int>>result=newList<List<int>>();// Place queensplaceQueens(0,mat,result);returnresult;}publicstaticvoidMain(){intn=4;List<List<int>>result=nQueen(n);foreach(varansinresult){foreach(variinans){Console.Write(i+" ");}Console.WriteLine();}}}
JavaScript
// Function to check if it is safe to placefunctionisSafe(mat,row,col){letn=mat.length;leti,j;// Check this col on upper sidefor(i=0;i<row;i++)if(mat[i][col])return0;// Check upper diagonal on left sidefor(i=row-1,j=col-1;i>=0&&j>=0;i--,j--)if(mat[i][j])return0;// Check upper diagonal on right sidefor(i=row-1,j=col+1;j<n&&i>=0;i--,j++)if(mat[i][j])return0;return1;}// Recursive function to place queensfunctionplaceQueens(row,mat,result){letn=mat.length;// base case: If all queens are placedif(row===n){// store current solutionletans=[];for(leti=0;i<n;i++){for(letj=0;j<n;j++){if(mat[i][j]){ans.push(j+1);}}}result.push(ans);return;}// Consider the row and try placing// queen in all columns one by onefor(leti=0;i<n;i++){// Check if the queen can be placedif(isSafe(mat,row,i)){mat[row][i]=1;placeQueens(row+1,mat,result);// backtrackmat[row][i]=0;}}}// Function to find all solutionsfunctionnQueen(n){// Initialize the boardletmat=Array.from({length:n},()=>Array(n).fill(0));letresult=[];// Place queensplaceQueens(0,mat,result);returnresult;}// Driver codeletn=4;letresult=nQueen(n);for(letansofresult){console.log(ans.join(' '));}
Output
2 4 1 3
3 1 4 2
Time Complexity: O(n!) We try placing queens in different positions, and choices reduce at each step due to conflicts. Auxiliary Space: O(n^2) We use an n × n board and recursion stack for backtracking.
[Expected Approach 1] Backtracking with Hashing
This is mainly an optimization over the above approach, we optimize the isSafe() by using three arrays to track occupied columns and diagonals. A position is considered valid only if its column and both diagonals are free. When placing a queen, mark these arrays, and while backtracking, unmark them. This allows checking safe positions in constant time O(1).
C++
#include<iostream>#include<vector>usingnamespacestd;// Recursive function to place queensvoidplaceQueens(inti,vector<int>&cols,vector<int>&leftDiagonal,vector<int>&rightDiagonal,vector<int>&cur,vector<vector<int>>&result){intn=cols.size();// base case: If all queens are placedif(i==n){result.push_back(cur);return;}// Consider the row and try placing// queen in all columns one by onefor(intj=0;j<n;j++){// Check if the queen can be placedif(cols[j]||rightDiagonal[i+j]||leftDiagonal[i-j+n-1])continue;// mark the cell occupiedcols[j]=1;rightDiagonal[i+j]=1;leftDiagonal[i-j+n-1]=1;cur.push_back(j+1);placeQueens(i+1,cols,leftDiagonal,rightDiagonal,cur,result);// remove the queen from current cellcur.pop_back();cols[j]=0;rightDiagonal[i+j]=0;leftDiagonal[i-j+n-1]=0;}}// Function to find the solution// to the N-Queens problemvector<vector<int>>nQueen(intn){// array to mark the occupied cellsvector<int>cols(n,0);vector<int>leftDiagonal(n*2,0);vector<int>rightDiagonal(n*2,0);vector<int>cur;vector<vector<int>>result;// Place queensplaceQueens(0,cols,leftDiagonal,rightDiagonal,cur,result);returnresult;}intmain(){intn=4;vector<vector<int>>ans=nQueen(n);for(auto&a:ans){for(autoi:a){cout<<i<<" ";}cout<<endl;}return0;}
Java
importjava.util.ArrayList;classGFG{// Recursive function to place queensstaticvoidplaceQueens(inti,int[]cols,int[]leftDiagonal,int[]rightDiagonal,ArrayList<Integer>cur,ArrayList<ArrayList<Integer>>result){intn=cols.length;// base case: If all queens are placedif(i==n){result.add(newArrayList<>(cur));return;}// Consider the row and try placing// queen in all columns one by onefor(intj=0;j<n;j++){// Check if the queen can be placedif(cols[j]==1||rightDiagonal[i+j]==1||leftDiagonal[i-j+n-1]==1)continue;// mark the cell occupiedcols[j]=1;rightDiagonal[i+j]=1;leftDiagonal[i-j+n-1]=1;cur.add(j+1);placeQueens(i+1,cols,leftDiagonal,rightDiagonal,cur,result);// remove the queen from current cellcur.remove(cur.size()-1);cols[j]=0;rightDiagonal[i+j]=0;leftDiagonal[i-j+n-1]=0;}}// Function to find the solution// to the N-Queens problemstaticArrayList<ArrayList<Integer>>nQueen(intn){// array to mark the occupied cellsint[]cols=newint[n];int[]leftDiagonal=newint[n*2];int[]rightDiagonal=newint[n*2];ArrayList<Integer>cur=newArrayList<>();ArrayList<ArrayList<Integer>>result=newArrayList<>();// Place queensplaceQueens(0,cols,leftDiagonal,rightDiagonal,cur,result);returnresult;}publicstaticvoidmain(String[]args){intn=4;ArrayList<ArrayList<Integer>>ans=nQueen(n);for(ArrayList<Integer>a:ans){for(inti:a){System.out.print(i+" ");}System.out.println();}}}
Python
# Recursive function to place queensdefplaceQueens(i,cols,leftDiagonal,rightDiagonal,cur,result):n=len(cols)# base case: If all queens are placedifi==n:result.append(cur[:])return# Consider the row and try placing# queen in all columns one by oneforjinrange(n):# Check if the queen can be placedifcols[j]orrightDiagonal[i+j]orleftDiagonal[i-j+n-1]:continue# mark the cell occupiedcols[j]=1rightDiagonal[i+j]=1leftDiagonal[i-j+n-1]=1cur.append(j+1)placeQueens(i+1,cols,leftDiagonal,rightDiagonal,cur,result)# remove the queen from current cellcur.pop()cols[j]=0rightDiagonal[i+j]=0leftDiagonal[i-j+n-1]=0# Function to find the solution# to the N-Queens problemdefnQueen(n):# array to mark the occupied cellscols=[0]*nleftDiagonal=[0]*(2*n)rightDiagonal=[0]*(2*n)cur=[]result=[]# Place queensplaceQueens(0,cols,leftDiagonal,rightDiagonal,cur,result)returnresultif__name__=="__main__":n=4ans=nQueen(n)forainans:print(" ".join(map(str,a)))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Recursive function to place queensstaticvoidplaceQueens(inti,int[]cols,int[]leftDiagonal,int[]rightDiagonal,List<int>cur,List<List<int>>result){intn=cols.Length;// base case: If all queens are placedif(i==n){result.Add(newList<int>(cur));return;}// Consider the row and try placing// queen in all columns one by onefor(intj=0;j<n;j++){// Check if the queen can be placedif(cols[j]==1||rightDiagonal[i+j]==1||leftDiagonal[i-j+n-1]==1)continue;// mark the cell occupiedcols[j]=1;rightDiagonal[i+j]=1;leftDiagonal[i-j+n-1]=1;cur.Add(j+1);placeQueens(i+1,cols,leftDiagonal,rightDiagonal,cur,result);// remove the queen from current cellcur.RemoveAt(cur.Count-1);cols[j]=0;rightDiagonal[i+j]=0;leftDiagonal[i-j+n-1]=0;}}// Function to find the solution// to the N-Queens problemstaticList<List<int>>nQueen(intn){// array to mark the occupied cellsint[]cols=newint[n];int[]leftDiagonal=newint[2*n];int[]rightDiagonal=newint[2*n];List<int>cur=newList<int>();List<List<int>>result=newList<List<int>>();// Place queensplaceQueens(0,cols,leftDiagonal,rightDiagonal,cur,result);returnresult;}staticvoidMain(){intn=4;List<List<int>>ans=nQueen(n);foreach(varainans){Console.WriteLine(string.Join(" ",a));}}}
JavaScript
// Recursive function to place queensfunctionplaceQueens(i,cols,leftDiagonal,rightDiagonal,cur,result){constn=cols.length;// base case: If all queens are placedif(i===n){result.push([...cur]);return;}// Consider the row and try placing// queen in all columns one by onefor(letj=0;j<n;j++){// Check if the queen can be placedif(cols[j]||rightDiagonal[i+j]||leftDiagonal[i-j+n-1]){continue;}// mark the cell occupiedcols[j]=1;rightDiagonal[i+j]=1;leftDiagonal[i-j+n-1]=1;cur.push(j+1);placeQueens(i+1,cols,leftDiagonal,rightDiagonal,cur,result);// remove the queen from current cellcur.pop();cols[j]=0;rightDiagonal[i+j]=0;leftDiagonal[i-j+n-1]=0;}}// Function to find the solution// to the N-Queens problemfunctionnQueen(n){// array to mark the occupied cellsconstcols=newArray(n).fill(0);constleftDiagonal=newArray(2*n).fill(0);constrightDiagonal=newArray(2*n).fill(0);constcur=[];constresult=[];// Place queensplaceQueens(0,cols,leftDiagonal,rightDiagonal,cur,result);returnresult;}// Driven Codeconstn=4;constans=nQueen(n);ans.forEach(a=>{console.log(a.join(" "));});
Output
2 4 1 3
3 1 4 2
Time Complexity: O(n!) – we try placing a queen in every row recursively, pruning invalid positions using the arrays. Auxiliary Space: O(n)
[Expected Approach 2] Backtracking with Bit-masking - O(n!) Time and O(n) Space
This is a further optimization for small board sizes. The idea is to use three variables to track occupied rows and diagonals. At each step, use bit operations to quickly find safe positions. Place a queen, update the variables, and move forward; if no position works, backtrack and try other options until all solutions are found.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to check if the current placement is safeboolisSafe(introw,intcol,introws,intld,intrd,intn){return!((rows>>row)&1)&&!((ld>>(row+col))&1)&&!((rd>>(row-col+n))&1);}// Recursive function to generate all possible permutationsvoidnQueenUtil(intcol,intn,vector<int>&board,vector<vector<int>>&res,introws,intld,intrd){// If all queens are placed, add into resif(col>n){res.push_back(board);return;}// Try placing a queen in each row// of the current columnfor(introw=1;row<=n;++row){// Check if it's safe to place the queenif(isSafe(row,col,rows,ld,rd,n)){// Place the queenboard.push_back(row);// Recur to place the next queennQueenUtil(col+1,n,board,res,rows|(1<<row),(ld|(1<<(row+col))),(rd|(1<<(row-col+n))));// Backtrack: remove the queenboard.pop_back();}}}// Main function to find all distinct // res to the n-queens puzzlevector<vector<int>>nQueen(intn){vector<vector<int>>res;// Current board configurationvector<int>board;// Start solving from the first columnnQueenUtil(1,n,board,res,0,0,0);returnres;}intmain(){intn=4;vector<vector<int>>res=nQueen(n);for(inti=0;i<res.size();i++){cout<<"[";for(intj=0;j<n;++j){cout<<res[i][j];if(j!=n-1)cout<<" ";}cout<<"]\n";}return0;}
Java
importjava.util.*;classGfG{// Function to check if the current placement is safestaticbooleanisSafe(introw,intcol,introws,intld,intrd,intn){return!(((rows>>row)&1)==1)&&!(((ld>>(row+col))&1)==1)&&!(((rd>>(row-col+n))&1)==1);}// Recursive function to generate all possible permutationsstaticvoidnQueenUtil(intcol,intn,ArrayList<Integer>board,ArrayList<ArrayList<Integer>>res,introws,intld,intrd){// If all queens are placed, add into resif(col>n){res.add(newArrayList<>(board));return;}// Try placing a queen in each row// of the current columnfor(introw=1;row<=n;++row){// Check if it's safe to place the queenif(isSafe(row,col,rows,ld,rd,n)){// Place the queenboard.add(row);// Recur to place the next queennQueenUtil(col+1,n,board,res,rows|(1<<row),(ld|(1<<(row+col))),(rd|(1<<(row-col+n))));// Backtrack: remove the queenboard.remove(board.size()-1);}}}// Main function to find all distinct // res to the n-queens puzzlestaticArrayList<ArrayList<Integer>>nQueen(intn){ArrayList<ArrayList<Integer>>res=newArrayList<>();// Current board configurationArrayList<Integer>board=newArrayList<>();// Start solving from the first columnnQueenUtil(1,n,board,res,0,0,0);returnres;}publicstaticvoidmain(String[]args){intn=4;ArrayList<ArrayList<Integer>>res=nQueen(n);for(ArrayList<Integer>solution:res){System.out.print("[");for(intj=0;j<n;++j){System.out.print(solution.get(j));if(j!=n-1)System.out.print(" ");}System.out.println("]");}}}
Python
# Function to check if the current placement is safedefisSafe(row,col,rows,ld,rd,n):returnnot((rows>>row)&1)and \
not((ld>>(row+col))&1)and \
not((rd>>(row-col+n))&1)# Recursive function to generate all possible permutationsdefnQueenUtil(col,n,board,res,rows,ld,rd):# If all queens are placed, add into resifcol>n:res.append(board[:])return# Try placing a queen in each row# of the current columnforrowinrange(1,n+1):# Check if it's safe to place the queenifisSafe(row,col,rows,ld,rd,n):# Place the queenboard.append(row)# Recur to place the next queennQueenUtil(col+1,n,board,res,rows|(1<<row),(ld|(1<<(row+col))),(rd|(1<<(row-col+n))))# Backtrack: remove the queenboard.pop()# Main function to find all distinct # res to the n-queens puzzledefnQueen(n):res=[]# Current board configurationboard=[]# Start solving from the first columnnQueenUtil(1,n,board,res,0,0,0)returnresif__name__=="__main__":n=4res=nQueen(n)forsolutioninres:print("[",end="")forjinrange(n):print(solution[j],end="")ifj!=n-1:print(" ",end="")print("]")
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to check if the current placement is safestaticboolisSafe(introw,intcol,introws,intld,intrd,intn){return!(((rows>>row)&1)==1)&&!(((ld>>(row+col))&1)==1)&&!(((rd>>(row-col+n))&1)==1);}// Recursive function to generate all possible permutationsstaticvoidnQueenUtil(intcol,intn,List<int>board,List<List<int>>res,introws,intld,intrd){// If all queens are placed, add into resif(col>n){res.Add(newList<int>(board));return;}// Try placing a queen in each row// of the current columnfor(introw=1;row<=n;++row){// Check if it's safe to place the queenif(isSafe(row,col,rows,ld,rd,n)){// Place the queenboard.Add(row);// Recur to place the next queennQueenUtil(col+1,n,board,res,rows|(1<<row),(ld|(1<<(row+col))),(rd|(1<<(row-col+n))));// Backtrack: remove the queenboard.RemoveAt(board.Count-1);}}}// Main function to find all distinct // res to the n-queens puzzlestaticList<List<int>>nQueen(intn){List<List<int>>res=newList<List<int>>();// Current board configurationList<int>board=newList<int>();// Start solving from the first columnnQueenUtil(1,n,board,res,0,0,0);returnres;}staticvoidMain(){intn=4;List<List<int>>res=nQueen(n);foreach(varsolutioninres){Console.Write("[");for(intj=0;j<n;++j){Console.Write(solution[j]);if(j!=n-1)Console.Write(" ");}Console.WriteLine("]");}}}
JavaScript
// Function to check if the current placement is safefunctionisSafe(row,col,rows,ld,rd,n){return!((rows>>row)&1)&&!((ld>>(row+col))&1)&&!((rd>>(row-col+n))&1);}// Recursive function to generate all possible permutationsfunctionnQueenUtil(col,n,board,res,rows,ld,rd){// If all queens are placed, add into resif(col>n){res.push([...board]);return;}// Try placing a queen in each row// of the current columnfor(letrow=1;row<=n;++row){// Check if it's safe to place the queenif(isSafe(row,col,rows,ld,rd,n)){// Place the queenboard.push(row);// Recur to place the next queennQueenUtil(col+1,n,board,res,rows|(1<<row),(ld|(1<<(row+col))),(rd|(1<<(row-col+n))));// Backtrack: remove the queenboard.pop();}}}// Main function to find all distinct // res to the n-queens puzzlefunctionnQueen(n){letres=[];// Current board configurationletboard=[];// Start solving from the first columnnQueenUtil(1,n,board,res,0,0,0);returnres;}// Driver Codeletn=4;letres=nQueen(n);for(leti=0;i<res.length;i++){process.stdout.write("[");for(letj=0;j<n;++j){process.stdout.write(res[i][j].toString());if(j!==n-1)process.stdout.write(" ");}console.log("]");}