Skip to content

Commit e2ce2e0

Browse files
committed
051
1 parent 6fe955f commit e2ce2e0

File tree

3 files changed

+151
-0
lines changed

3 files changed

+151
-0
lines changed

051/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Basically, backtracking is an efficient way for us to get the answer towards this problem.
2+
The direct way is to put the queue row by row. When putting one queue towards a row, the program has to check the validity of this position; that is, determine whether there exists one queue in `current column`, `45 degree diagonal` and `135 degree diagonal`. If so, try another position in this row; If not, put the queue and explore next row.
3+
4+
But wait! Can we speed up the program? Of course, you might found the current way for backtracking costs half of the time. Now the concern becomes whether there is one way to directly check the validity of one position.
5+
6+
The answer is to use one flag array called `flags`. For position (row, col), `flags[col]` tells whether there is one queue in column `col`; `flags[n + col + row]` and `flags[n + 2 * n + 1 + n - 1 + col - row]` respectively suggests the existence of queue on `45 deg diagonal` and `135 deg diagonal`.
7+
8+
Now, the time complexity becomes `O(n * n)` where n is the length of the chessboard.
9+
10+
https://discuss.leetcode.com/topic/13617/accepted-4ms-c-solution-use-backtracking-and-bitmask-easy-understand
11+
12+
Main points:
13+
1. go row by row
14+
2. one array indicating if the column or diagonal had a queue before

051/main.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @param {number} n
3+
* @return {string[][]}
4+
*/
5+
var solveNQueens = function(n) {
6+
const grids = Array.from({ length: n }, () => {
7+
return Array.from({ length: n }, () => '.')
8+
})
9+
10+
const ans = []
11+
12+
function isConflicted (x, y) {
13+
for (let i = 0; i < x; i++) {
14+
if (grids[i][y] === 'Q') {
15+
return true
16+
}
17+
}
18+
let i = x - 1
19+
let j = y - 1
20+
while (i >= 0 && j >= 0) {
21+
if (grids[i--][j--] === 'Q') {
22+
return true
23+
}
24+
}
25+
i = x - 1
26+
j = y + 1
27+
while (i >= 0 && j < n) {
28+
if (grids[i--][j++] === 'Q') {
29+
return true
30+
}
31+
}
32+
return false
33+
}
34+
35+
function mirror (grids) {
36+
return grids.map((item) => item.slice().reverse())
37+
}
38+
39+
function fillGrids (x, callback) {
40+
if (x >= n) {
41+
return callback(grids)
42+
}
43+
for (let i = 0; i < n; i++) {
44+
if (!isConflicted(x, i)) {
45+
grids[x][i] = 'Q'
46+
fillGrids(x + 1, callback)
47+
grids[x][i] = '.'
48+
}
49+
}
50+
}
51+
52+
for (let i = 0; i < Math.floor(n / 2); i++) {
53+
grids[0][i] = 'Q'
54+
fillGrids(1, (grids) => {
55+
ans.push(grids.map(item => item.slice()), mirror(grids))
56+
})
57+
grids[0][i] = '.'
58+
}
59+
if (n % 2 === 1) {
60+
grids[0][Math.floor(n / 2)] = 'Q'
61+
fillGrids(1, (grids) => {
62+
ans.push(grids.map(item => item.slice()))
63+
})
64+
grids[0][Math.floor(n / 2)] = '.'
65+
}
66+
67+
return ans.map((grids) => {
68+
return grids.map(row => row.join(''))
69+
})
70+
};
71+
72+
console.log(solveNQueens(6))

051/main.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import math
2+
3+
class Solution(object):
4+
def solveNQueens(self, n):
5+
"""
6+
:type n: int
7+
:rtype: List[List[str]]
8+
"""
9+
def is_conflicted(grids, x, y):
10+
for i in range(0, x):
11+
if grids[i] & (1 << (n - y - 1)):
12+
return True
13+
14+
i, j = x - 1, y - 1
15+
while i >= 0 and j >= 0:
16+
if grids[i] & (1 << (n - j - 1)):
17+
return True
18+
i, j = i - 1, j - 1
19+
20+
i, j = x - 1, y + 1
21+
while i >= 0 and j < n:
22+
if grids[i] & (1 << (n - j - 1)):
23+
return True
24+
i, j = i - 1, j + 1
25+
26+
return False
27+
28+
def fill(grids, x, ans):
29+
if x >= n:
30+
ans.append(grids[:])
31+
return
32+
for i in range(0, n):
33+
if not is_conflicted(grids, x, i):
34+
grids[x] = 1 << (n - i - 1)
35+
fill(grids, x + 1, ans)
36+
grids[x] = 0
37+
38+
def mirror(x, n):
39+
return 1 << (n - 1 - int(math.log(x) / math.log(2)))
40+
41+
def grids_to_strs(grids):
42+
res = []
43+
for item in grids:
44+
s = '.' * n
45+
pivot = n - 1 - int(math.log(item) / math.log(2))
46+
s = s[0:pivot] + 'Q' + s[pivot + 1:]
47+
res.append(s)
48+
return res
49+
50+
ans, grids = [], [ 0 for i in range(n) ]
51+
for i in range(0, n / 2):
52+
grids[0] = 1 << (n - 1 - i)
53+
fill(grids, 1, ans)
54+
grids[0] = 0
55+
56+
ans.extend([ [mirror(row, n) for row in rows] for rows in ans ])
57+
58+
if n % 2:
59+
grids[0] = 1 << n / 2
60+
fill(grids, 1, ans)
61+
62+
return [ grids_to_strs(rows) for rows in ans ]
63+
64+
s = Solution()
65+
print(s.solveNQueens(7))

0 commit comments

Comments
 (0)