问题描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
提示:
皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一到七步,可进可退。(引用自 百度百科 - 皇后 )
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
解答
''' 递归dfs+回溯,没用剪枝,目前还不知道哪些可以剪。。。 ''' class Solution(object): def solveNQueens(self, n): if n == 1: return [["Q"]] if n > 1 and n < 4: return [] global board global flag global result board = [[0 for _ in range(n)] for _ in range(n)] result = [] flag = 0 def stretch(x,y,l,r,u,d,sign): if l == 1 and r == 0 and u == 0 and d == 0 and y-1 >= 0: if board[x][y-1] >= 10000: flag = 1 if sign == 1: board[x][y-1] += 1 stretch(x,y-1,1,0,0,0,1) else: board[x][y-1] -= 1 stretch(x,y-1,1,0,0,0,0) elif l == 0 and r == 1 and u == 0 and d == 0 and y+1 < n: if board[x][y+1] >= 10000: flag = 1 if sign == 1: board[x][y+1] += 1 stretch(x,y+1,0,1,0,0,1) else: board[x][y+1] -= 1 stretch(x,y+1,0,1,0,0,0) elif l == 0 and r == 0 and u == 1 and d == 0 and x-1 >= 0: if board[x-1][y] >= 10000: flag = 1 if sign == 1: board[x-1][y] += 1 stretch(x-1,y,0,0,1,0,1) else: board[x-1][y] -= 1 stretch(x-1,y,0,0,1,0,0) elif l == 0 and r == 0 and u == 0 and d == 1 and x+1 < n: if board[x+1][y] >= 10000: flag = 1 if sign == 1: board[x+1][y] += 1 stretch(x+1,y,0,0,0,1,1) else: board[x+1][y] -= 1 stretch(x+1,y,0,0,0,1,0) elif l == 1 and r == 0 and u == 1 and d == 0 and y-1 >= 0 and x-1 >= 0: if board[x-1][y-1] >= 10000: flag = 1 if sign == 1: board[x-1][y-1] += 1 stretch(x-1,y-1,1,0,1,0,1) else: board[x-1][y-1] -= 1 stretch(x-1,y-1,1,0,1,0,0) elif l == 1 and r == 0 and u == 0 and d == 1 and y-1 >= 0 and x+1 < n: if board[x+1][y-1] >= 10000: flag = 1 if sign == 1: board[x+1][y-1] += 1 stretch(x+1,y-1,1,0,0,1,1) else: board[x+1][y-1] -= 1 stretch(x+1,y-1,1,0,0,1,0) elif l == 0 and r == 1 and u == 0 and d == 1 and y+1 < n and x+1 < n: if board[x+1][y+1] >= 10000: flag = 1 if sign == 1: board[x+1][y+1] += 1 stretch(x+1,y+1,0,1,0,1,1) else: board[x+1][y+1] -= 1 stretch(x+1,y+1,0,1,0,1,0) elif l == 0 and r == 1 and u == 1 and d == 0 and y+1 < n and x-1 >= 0: if board[x-1][y+1] >= 10000: flag = 1 if sign == 1: board[x-1][y+1] += 1 stretch(x-1,y+1,0,1,1,0,1) else: board[x-1][y+1] -= 1 stretch(x-1,y+1,0,1,1,0,0) else:return def remove(board,x,y): board[x][y] -= 10000 stretch(x,y,0,1,0,0,0) stretch(x,y,1,0,0,0,0) stretch(x,y,0,0,1,0,0) stretch(x,y,0,0,0,1,0) stretch(x,y,1,0,1,0,0) stretch(x,y,1,0,0,1,0) stretch(x,y,0,1,0,1,0) stretch(x,y,0,1,1,0,0) def place_the_queen(x,y): global board global flag global count if x >= 0 and x < n and y >= 0 and y < n: if board[x][y] < 1: flag = 0 board[x][y] += 10000 stretch(x,y,0,1,0,0,1) stretch(x,y,1,0,0,0,1) stretch(x,y,0,0,1,0,1) stretch(x,y,0,0,0,1,1) stretch(x,y,1,0,1,0,1) stretch(x,y,1,0,0,1,1) stretch(x,y,0,1,0,1,1) stretch(x,y,0,1,1,0,1) else: flag = 1 return -1 if flag == 1: remove(board,x,y) flag = 0 return -1 else: return 1 def find_queen(board,row): for i in range(0,n): if board[row][i] >= 10000: return i return -1 def to_result(result,board): result.append([]) for i in board: result[-1].append("") for j in i: if j >= 10000: result[-1][-1] += 'Q' else: result[-1][-1] += '.' def backtrack(board,x,y): global result if y < n: if place_the_queen(x,y) == 1: if x == n-1: to_result(result,board) remove(board,x,y) y = n else: backtrack(board,x+1,0) else: backtrack(board,x,y+1) if y == n: column = find_queen(board,x-1) remove(board,x-1,column) if x-1 == 0 and column+1 == n: return else: backtrack(board,x-1,column+1) backtrack(board,0,0) return result
'''
递归dfs+回溯,没用剪枝,目前还不知道哪些可以剪。。。
'''
class Solution(
object):
def solveNQueens(
self, n):
if n ==
1:
return [[
"Q"]]
if n >
1
and n <
4:
return []
global board
global flag
global result
board = [[
0
for _
in
range(n)]
for _
in
range(n)]
result = []
flag =
0
def stretch(x,y,l,r,u,d,sign):
if l ==
1
and r ==
0
and u ==
0
and d ==
0
and y
-1 >=
0:
if board[x][y
-1] >=
10000:
flag =
1
if sign ==
1:
board[x][y
-1] +=
1
stretch(x,y
-1,
1,
0,
0,
0,
1)
else:
board[x][y
-1] -=
1
stretch(x,y
-1,
1,
0,
0,
0,
0)
elif l ==
0
and r ==
1
and u ==
0
and d ==
0
and y+
1 < n:
if board[x][y+
1] >=
10000:
flag =
1
if sign ==
1:
board[x][y+
1] +=
1
stretch(x,y+
1,
0,
1,
0,
0,
1)
else:
board[x][y+
1] -=
1
stretch(x,y+
1,
0,
1,
0,
0,
0)
elif l ==
0
and r ==
0
and u ==
1
and d ==
0
and x
-1 >=
0:
if board[x
-1][y] >=
10000:
flag =
1
if sign ==
1:
board[x
-1][y] +=
1
stretch(x
-1,y,
0,
0,
1,
0,
1)
else:
board[x
-1][y] -=
1
stretch(x
-1,y,
0,
0,
1,
0,
0)
elif l ==
0
and r ==
0
and u ==
0
and d ==
1
and x+
1 < n:
if board[x+
1][y] >=
10000:
flag =
1
if sign ==
1:
board[x+
1][y] +=
1
stretch(x+
1,y,
0,
0,
0,
1,
1)
else:
board[x+
1][y] -=
1
stretch(x+
1,y,
0,
0,
0,
1,
0)
elif l ==
1
and r ==
0
and u ==
1
and d ==
0
and y
-1 >=
0
and x
-1 >=
0:
if board[x
-1][y
-1] >=
10000:
flag =
1
if sign ==
1:
board[x
-1][y
-1] +=
1
stretch(x
-1,y
-1,
1,
0,
1,
0,
1)
else:
board[x
-1][y
-1] -=
1
stretch(x
-1,y
-1,
1,
0,
1,
0,
0)
elif l ==
1
and r ==
0
and u ==
0
and d ==
1
and y
-1 >=
0
and x+
1 < n:
if board[x+
1][y
-1] >=
10000:
flag =
1
if sign ==
1:
board[x+
1][y
-1] +=
1
stretch(x+
1,y
-1,
1,
0,
0,
1,
1)
else:
board[x+
1][y
-1] -=
1
stretch(x+
1,y
-1,
1,
0,
0,
1,
0)
elif l ==
0
and r ==
1
and u ==
0
and d ==
1
and y+
1 < n
and x+
1 < n:
if board[x+
1][y+
1] >=
10000:
flag =
1
if sign ==
1:
board[x+
1][y+
1] +=
1
stretch(x+
1,y+
1,
0,
1,
0,
1,
1)
else:
board[x+
1][y+
1] -=
1
stretch(x+
1,y+
1,
0,
1,
0,
1,
0)
elif l ==
0
and r ==
1
and u ==
1
and d ==
0
and y+
1 < n
and x
-1 >=
0:
if board[x
-1][y+
1] >=
10000:
flag =
1
if sign ==
1:
board[x
-1][y+
1] +=
1
stretch(x
-1,y+
1,
0,
1,
1,
0,
1)
else:
board[x
-1][y+
1] -=
1
stretch(x
-1,y+
1,
0,
1,
1,
0,
0)
else:
return
def remove(board,x,y):
board[x][y] -=
10000
stretch(x,y,
0,
1,
0,
0,
0)
stretch(x,y,
1,
0,
0,
0,
0)
stretch(x,y,
0,
0,
1,
0,
0)
stretch(x,y,
0,
0,
0,
1,
0)
stretch(x,y,
1,
0,
1,
0,
0)
stretch(x,y,
1,
0,
0,
1,
0)
stretch(x,y,
0,
1,
0,
1,
0)
stretch(x,y,
0,
1,
1,
0,
0)
def place_the_queen(x,y):
global board
global flag
global count
if x >=
0
and x < n
and y >=
0
and y < n:
if board[x][y] <
1:
flag =
0
board[x][y] +=
10000
stretch(x,y,
0,
1,
0,
0,
1)
stretch(x,y,
1,
0,
0,
0,
1)
stretch(x,y,
0,
0,
1,
0,
1)
stretch(x,y,
0,
0,
0,
1,
1)
stretch(x,y,
1,
0,
1,
0,
1)
stretch(x,y,
1,
0,
0,
1,
1)
stretch(x,y,
0,
1,
0,
1,
1)
stretch(x,y,
0,
1,
1,
0,
1)
else:
flag =
1
return
-1
if flag ==
1:
remove(board,x,y)
flag =
0
return
-1
else:
return
1
def find_queen(board,row):
for i
in
range(
0,n):
if board[row][i] >=
10000:
return i
return
-1
def to_result(result,board):
result.append([])
for i
in board:
result[
-1].append(
"")
for j
in i:
if j >=
10000:
result[
-1][
-1] +=
'Q'
else:
result[
-1][
-1] +=
'.'
def backtrack(board,x,y):
global result
if y < n:
if place_the_queen(x,y) ==
1:
if x == n
-1:
to_result(result,board)
remove(board,x,y)
y = n
else:
backtrack(board,x+
1,
0)
else:
backtrack(board,x,y+
1)
if y == n:
column = find_queen(board,x
-1)
remove(board,x
-1,column)
if x
-1 ==
0
and column+
1 == n:
return
else:
backtrack(board,x
-1,column+
1)
backtrack(board,
0,
0)
return result