forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 1
/
n-queens.py
56 lines (49 loc) · 2 KB
/
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
# Time: O(n!)
# Space: O(n)
class Solution(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
def dfs(curr, cols, main_diag, anti_diag, result):
row, n = len(curr), len(cols)
if row == n:
result.append(map(lambda x: '.'*x + "Q" + '.'*(n-x-1), curr))
return
for i in xrange(n):
if cols[i] or main_diag[row+i] or anti_diag[row-i+n]:
continue
cols[i] = main_diag[row+i] = anti_diag[row-i+n] = True
curr.append(i)
dfs(curr, cols, main_diag, anti_diag, result)
curr.pop()
cols[i] = main_diag[row+i] = anti_diag[row-i+n] = False
result = []
cols, main_diag, anti_diag = [False]*n, [False]*(2*n), [False]*(2*n)
dfs([], cols, main_diag, anti_diag, result)
return result
# For any point (x,y), if we want the new point (p,q) don't share the same row, column, or diagonal.
# then there must have ```p+q != x+y``` and ```p-q!= x-y```
# the former focus on eliminate 'left bottom right top' diagonal;
# the latter focus on eliminate 'left top right bottom' diagonal
# - col_per_row: the list of column index per row
# - cur_row:current row we are seraching for valid column
# - xy_diff:the list of x-y
# - xy_sum:the list of x+y
class Solution2(object):
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
def dfs(col_per_row, xy_diff, xy_sum):
cur_row = len(col_per_row)
if cur_row == n:
ress.append(col_per_row)
for col in range(n):
if col not in col_per_row and cur_row-col not in xy_diff and cur_row+col not in xy_sum:
dfs(col_per_row+[col], xy_diff+[cur_row-col], xy_sum+[cur_row+col])
ress = []
dfs([], [], [])
return [['.'*i + 'Q' + '.'*(n-i-1) for i in res] for res in ress]