51. N皇后-递归dfs+回溯-困难

问题描述

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

你可能感兴趣的:(51. N皇后-递归dfs+回溯-困难)