Skip to content

Commit 2e5a08c

Browse files
authored
Merge pull request #1046 from katarianikita2003/main
Create 0051-N-Queens-Problem
2 parents 70804d3 + 797f743 commit 2e5a08c

File tree

1 file changed

+302
-0
lines changed

1 file changed

+302
-0
lines changed
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
---
2+
id: N-Queens-Puzzle
3+
title: N-Queens Puzzle
4+
sidebar_label: N-Queens Puzzle
5+
tags:
6+
- Backtracking
7+
- Recursion
8+
- Algorithm
9+
description: 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.
10+
---
11+
12+
## Problem Description
13+
14+
| Problem Statement | Solution Link | LeetCode Profile |
15+
| :------------------------------------------------------ | :------------------------------------------------------------------------- | :------------------------------------------------------ |
16+
| [n-queens-puzzle](https://leetcode.com/problems/N-Queens-Puzzle/description/) | [N-Queens-Puzzle Solution on LeetCode](https://leetcode.com/problems/N-Queens-Puzzle/solutions/) | [Nikita Saini](https://leetcode.com/u/Saini_Nikita/) |
17+
18+
## Problem Description:
19+
20+
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 all distinct solutions to the n-queens puzzle. You may return the answer in any order.
21+
22+
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space, respectively.
23+
24+
### Example 1
25+
26+
- **Input:** `n = 4`
27+
- **Output:** `[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]`
28+
- **Explanation:** `There exist two distinct solutions to the 4-queens puzzle as shown above`
29+
30+
### Example 2
31+
32+
- **Input:** `n = 1`
33+
- **Output:** `[["Q"]]`
34+
35+
### Constraints
36+
37+
- $1 \leq n \leq 9$
38+
39+
### Approach
40+
The problem can be solved using a backtracking approach. The idea is to place queens one by one on the board and check if the current placement is safe. If it is, we proceed to place the next queen. If it is not, we backtrack and try the next possible position.
41+
42+
### Solution in different languages
43+
44+
### Solution in Python
45+
```python
46+
def solveNQueens(n):
47+
def is_not_under_attack(row, col):
48+
return not (cols[col] or hills[row - col] or dales[row + col])
49+
50+
def place_queen(row, col):
51+
queens.add((row, col))
52+
cols[col] = 1
53+
hills[row - col] = 1
54+
dales[row + col] = 1
55+
56+
def remove_queen(row, col):
57+
queens.remove((row, col))
58+
cols[col] = 0
59+
hills[row - col] = 0
60+
dales[row + col] = 0
61+
62+
def add_solution():
63+
solution = []
64+
for _, col in sorted(queens):
65+
solution.append('.' * col + 'Q' + '.' * (n - col - 1))
66+
solutions.append(solution)
67+
68+
def backtrack(row = 0):
69+
for col in range(n):
70+
if is_not_under_attack(row, col):
71+
place_queen(row, col)
72+
if row + 1 == n:
73+
add_solution()
74+
else:
75+
backtrack(row + 1)
76+
remove_queen(row, col)
77+
78+
solutions = []
79+
queens = set()
80+
cols = [0] * n
81+
hills = [0] * (2 * n - 1)
82+
dales = [0] * (2 * n - 1)
83+
backtrack()
84+
return solutions
85+
```
86+
87+
### Solution in Java
88+
```java
89+
import java.util.ArrayList;
90+
import java.util.HashSet;
91+
import java.util.List;
92+
import java.util.Set;
93+
94+
class Solution {
95+
public List<List<String>> solveNQueens(int n) {
96+
List<List<String>> solutions = new ArrayList<>();
97+
Set<Integer> cols = new HashSet<>();
98+
Set<Integer> hills = new HashSet<>();
99+
Set<Integer> dales = new HashSet<>();
100+
backtrack(solutions, new ArrayList<>(), cols, hills, dales, n, 0);
101+
return solutions;
102+
}
103+
104+
private void backtrack(List<List<String>> solutions, List<Integer> queens, Set<Integer> cols, Set<Integer> hills, Set<Integer> dales, int n, int row) {
105+
if (row == n) {
106+
solutions.add(createBoard(queens, n));
107+
return;
108+
}
109+
for (int col = 0; col < n; col++) {
110+
if (cols.contains(col) || hills.contains(row - col) || dales.contains(row + col)) {
111+
continue;
112+
}
113+
queens.add(col);
114+
cols.add(col);
115+
hills.add(row - col);
116+
dales.add(row + col);
117+
backtrack(solutions, queens, cols, hills, dales, n, row + 1);
118+
queens.remove(queens.size() - 1);
119+
cols.remove(col);
120+
hills.remove(row - col);
121+
dales.remove(row + col);
122+
}
123+
}
124+
125+
private List<String> createBoard(List<Integer> queens, int n) {
126+
List<String> board = new ArrayList<>();
127+
for (int i = 0; i < n; i++) {
128+
char[] row = new char[n];
129+
for (int j = 0; j < n; j++) {
130+
row[j] = '.';
131+
}
132+
row[queens.get(i)] = 'Q';
133+
board.add(new String(row));
134+
}
135+
return board;
136+
}
137+
}
138+
```
139+
140+
### Solution in C++
141+
```cpp
142+
class Solution {
143+
public:
144+
vector<vector<string>> solveNQueens(int n) {
145+
vector<vector<string>> solutions;
146+
vector<int> queens(n, -1);
147+
vector<int> cols(n, 0), hills(2 * n - 1, 0), dales(2 * n - 1, 0);
148+
backtrack(solutions, queens, n, 0, cols, hills, dales);
149+
return solutions;
150+
}
151+
152+
private:
153+
void backtrack(vector<vector<string>>& solutions, vector<int>& queens, int n, int row, vector<int>& cols, vector<int>& hills, vector<int>& dales) {
154+
if (row == n) {
155+
solutions.push_back(createBoard(queens, n));
156+
return;
157+
}
158+
for (int col = 0; col < n; col++) {
159+
if (cols[col] || hills[row - col + n - 1] || dales[row + col]) {
160+
continue;
161+
}
162+
queens[row] = col;
163+
cols[col] = hills[row - col + n - 1] = dales[row + col] = 1;
164+
backtrack(solutions, queens, n, row + 1, cols, hills, dales);
165+
cols[col] = hills[row - col + n - 1] = dales[row + col] = 0;
166+
}
167+
}
168+
169+
vector<string> createBoard(vector<int>& queens, int n) {
170+
vector<string> board;
171+
for (int i = 0; i < n; i++) {
172+
string row(n, '.');
173+
row[queens[i]] = 'Q';
174+
board.push_back(row);
175+
}
176+
return board;
177+
}
178+
};
179+
```
180+
181+
### Solution in C
182+
```c
183+
#include <stdio.h>
184+
#include <stdlib.h>
185+
186+
void addSolution(int **solutions, int *queens, int n, int *returnSize) {
187+
for (int i = 0; i < n; i++) {
188+
for (int j = 0; j < n; j++) {
189+
solutions[*returnSize][i * n + j] = (queens[i] == j) ? 'Q' : '.';
190+
}
191+
}
192+
(*returnSize)++;
193+
}
194+
195+
void backtrack(int **solutions, int *queens, int *cols, int *hills, int *dales, int n, int row, int *returnSize) {
196+
if (row == n) {
197+
addSolution(solutions, queens, n, returnSize);
198+
return;
199+
}
200+
for (int col = 0; col < n; col++) {
201+
if (cols[col] || hills[row - col + n - 1] || dales[row + col]) {
202+
continue;
203+
}
204+
queens[row] = col;
205+
cols[col] = hills[row - col + n - 1] = dales[row + col] = 1;
206+
backtrack(solutions, queens, cols, hills, dales, n, row + 1, returnSize);
207+
cols[col] = hills[row - col + n - 1] = dales[row + col] = 0;
208+
}
209+
}
210+
211+
char*** solveNQueens(int n, int* returnSize, int** returnColumnSizes) {
212+
*returnSize = 0;
213+
int totalSolutions = 1;
214+
for (int i = 1; i <= n; i++) totalSolutions *= i;
215+
216+
char ***solutions = (char ***)malloc(totalSolutions * sizeof(char **));
217+
*returnColumnSizes = (int *)malloc(totalSolutions * sizeof(int));
218+
219+
for (int i = 0; i < totalSolutions; i++) {
220+
solutions[i] = (char **)malloc(n * sizeof(char *));
221+
for (int j = 0; j < n; j++) {
222+
solutions[i][j] = (char *)malloc((n + 1) * sizeof(char));
223+
}
224+
(*returnColumnSizes)[i] = n;
225+
}
226+
227+
int *queens = (int *)malloc(n * sizeof(int));
228+
int *cols = (int *)malloc(n * sizeof(int));
229+
int *hills = (int *)malloc((2 * n - 1) * sizeof(int));
230+
int *dales = (int *)malloc((2 * n - 1) * sizeof(int));
231+
for (int i = 0; i < n; i++) cols[i] = 0;
232+
for (int i = 0; i < 2 * n - 1; i++) hills[i] = dales[i] = 0;
233+
234+
backtrack(solutions, queens, cols, hills, dales, n, 0, returnSize);
235+
236+
return solutions;
237+
}
238+
```
239+
240+
### Solution in JavaScript
241+
```js
242+
var solveNQueens = function(n) {
243+
const solutions = [];
244+
const queens = [];
245+
const cols = new Set();
246+
const hills = new Set();
247+
const dales = new Set();
248+
249+
const backtrack = (row = 0) => {
250+
if (row === n) {
251+
solutions.push(createBoard(queens, n));
252+
return;
253+
}
254+
for (let col = 0; col < n; col++) {
255+
if (cols.has(col) || hills.has(row - col) || dales.has(row + col)) {
256+
continue;
257+
}
258+
queens.push(col);
259+
cols.add(col);
260+
hills.add(row - col);
261+
dales.add(row + col);
262+
backtrack(row + 1);
263+
queens.pop();
264+
cols.delete(col);
265+
hills.delete(row - col);
266+
dales.delete(row + col);
267+
}
268+
};
269+
270+
const createBoard = (queens, n) => {
271+
const board = [];
272+
for (let i = 0; i < n; i++) {
273+
let row = '.'.repeat(n).split('');
274+
row[queens[i]] = 'Q';
275+
board.push(row.join(''));
276+
}
277+
return board;
278+
};
279+
280+
backtrack();
281+
return solutions;
282+
};
283+
```
284+
285+
### Step-by-step Algorithm
286+
287+
1. Initialize Data Structures:
288+
- Create a list to store the solutions.
289+
- Create sets to keep track of columns, hills (main diagonals), and dales (anti-diagonals) that are under attack.
290+
291+
2. Backtracking Function:
292+
- Try placing a queen in each column of the current row.
293+
- Check if the current column, hill, or dale is under attack using the sets.
294+
- If placing a queen is safe, add the column to the list of queens and mark the column, hill, and dale as occupied.
295+
- Recursively call the backtracking function for the next row.
296+
- If a valid solution is found (when row equals n), add the solution to the list of solutions.
297+
- Backtrack by removing the queen and unmarking the column, hill, and dale.
298+
3. Create Board Representation:
299+
- Convert the list of queen positions into the board representation as a list of strings.
300+
301+
### Conclusion
302+
The n-queens puzzle, solved using backtracking, ensures no two queens attack each other on an n x n chessboard. Solutions are efficiently implemented in Python, Java, C++, C, and JavaScript.

0 commit comments

Comments
 (0)