-
Notifications
You must be signed in to change notification settings - Fork 0
/
51. N-Queens.py
130 lines (115 loc) · 4.01 KB
/
51. N-Queens.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class Solution:
# less space
def solveNQueensSlow(self, n: int) -> [[str]]:
res = []
queens = []
def backtrack(row):
if len(queens) == n:
board = ["." * n] * n
for qx, qy in queens:
board[qx] = board[qx][:qy] + "Q" + board[qx][qy + 1:] if qy < n - 1 else board[qx][:qy] + "Q"
res.append(board[:])
for j in range(n):
can_put = True
for qx, qy in queens:
if not (qx != row and qy != j and (abs(abs(qx) - abs(row)) != abs(abs(qy) - abs(j)))):
can_put = False
break
if can_put:
queens.append((row, j))
backtrack(row + 1)
queens.pop(-1)
return
backtrack(0)
return res
# less time
def solveNQueens(self, n: int) -> [[str]]:
res = []
queens = []
col_set = set()
dia_set = set()
anti_dia_set = set()
def backtrack(row):
if len(queens) == n:
board = ["." * n] * n
for qx, qy in queens:
board[qx] = board[qx][:qy] + "Q" + board[qx][qy + 1:] if qy < n - 1 else board[qx][:qy] + "Q"
res.append(board[:])
for j in range(n):
if j not in col_set and row - j not in dia_set and row + j not in anti_dia_set:
can_put = True
else:
can_put = False
if can_put:
queens.append((row, j))
col_set.add(j)
dia_set.add(row - j)
anti_dia_set.add(row + j)
backtrack(row + 1)
queens.pop(-1)
col_set.remove(j)
dia_set.remove(row - j)
anti_dia_set.remove(row + j)
return
backtrack(0)
return res
def solveNQueens2(self, n: int) -> [[str]]:
board = ["." * n] * n
res = []
def is_valid(row, column):
for i in range(row):
if board[i][column] == 'Q':
return False
i, j = row, column
while i >= 0 and j >= 0:
if board[i][j] == 'Q':
return False
i -= 1
j -= 1
i, j = row, column
while i >= 0 and j < n:
if board[i][j] == 'Q':
return False
i -= 1
j += 1
return True
def backtrack(row):
if row == n:
res.append(board[:])
for i in range(n):
if is_valid(row, i):
board[row] = i * "." + 'Q' + (n - i - 1) * "."
backtrack(row + 1)
board[row] = n * '.'
backtrack(0)
return res
def solveNQueens2Fast(self, n: int) -> [[str]]:
# for dias i - j is the same, for anti-dias i + j is the same
col_set = set()
dia_set = set()
anti_dia_set = set()
board = ["." * n] * n
res = []
def is_valid(i, j):
if j not in col_set and i - j not in dia_set and i + j not in anti_dia_set:
return True
else:
return False
def backtrack(row):
if row == n:
res.append(board[:])
for i in range(n):
if is_valid(row, i):
board[row] = i * "." + 'Q' + (n - i - 1) * "."
col_set.add(i)
dia_set.add(row - i)
anti_dia_set.add(row + i)
backtrack(row + 1)
col_set.remove(i)
dia_set.remove(row - i)
anti_dia_set.remove(row + i)
board[row] = n * '.'
backtrack(0)
return res
test = Solution()
print(test.solveNQueens(4))