N皇后

72 阅读2分钟

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n皇后问题研究的是如何将n个皇后放置在n×n的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数n,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的n 皇后问题的棋子放置方案,该方案中'Q''.'分别代表了皇后和空位。
image.png

思路
  1. 怎么回溯?
  • 一行一行加皇后;
  • 遍历每行能放的位置,即遍历所有可能性。
  1. 怎么判断能不能放?
  • 不在同一行、不在同一列和不在斜对角。
  1. 怎么通过代码实现判断?
  • 行:用递归树的高索引,自动增加;
  • 列:借鉴全排列题目的做法,使用辅助数组q,q[0...height-1]表示已经使用过的列,height以后的表示未使用的列。当该行已经确定一种位置,将其与q[i]交换;
  • 斜对角:只需判断左上角和右上角,左上角是[r-1,c-1],右上角是[r-1,c+1],使用循环一个一个判断。
看题解学到的可能加速的方法
  1. 实现快速判断斜对角
  • 左上角:同一斜线的行下标与列下标差相等;
  • 右上角:同一斜线的行下标与列下标之和相等;
  • 维护两个列表,判断当前位置的下标在这两个方向是否满足条件。
  1. 看力扣题解位运算
代码
class Solution(object):
    def solveNQueens(self, n):
        """
        :type n: int
        :rtype: List[List[str]]
        """
        q = [i for i in range(n)]
        def dfs(height):
            if height == n:
                result.append(["".join(row) for row in res_i])

            for i in range(height,n):
                flag = 0
                #左上角
                r = height - 1
                #注意当前情况的是q[i],不是q[height]
                c = q[i] - 1
                while r>=0 and c>=0 :
                    if res_i[r][c] == 'Q':
                        flag = 1
                        break
                    r = r-1
                    c = c-1
                    
                #右上角
                r = height - 1
                c = q[i] + 1
                while r>=0 and c<n :
                    if res_i[r][c] == 'Q':
                        flag = 1
                        break
                    r = r-1
                    c = c+1
                    
                #判断斜对角是否符合条件
                if flag == 1:
                    continue

                #修改对应位置的值
                res_i[height][q[i]] = 'Q'
                #height后的是可以使用的列
                q[i],q[height] = q[height],q[i]
                
                #递归
                dfs(height+1)

                #撤销操作
                q[i],q[height] = q[height],q[i]
                res_i[height][q[i]] = '.'

        res_i = [['.'] * n for _ in range(n)]
        result = list()
        dfs(0)
        return result