【每日一题】52. N-Queens II

在这里插入图片描述

这个讲解比较好理解:回溯法与N皇后问题
N皇后问题,题目意思是在N * N的棋盘当中放置N个皇后,这N个皇后要“和平相处”,若任意两个皇后处在同一行,同一列,或者同一对角线上,那么这两个皇后就要打起来。

先直观理解一下这题的解法,从第一行开始放置皇后,在每一行放置的时候都需要检查当前列是否能够可以放皇后,如果可以放置,OK,进入下一行,如果不能够放置,那么进入该行的下一列再进行判断,如果直到该行的末尾都无法放置皇后,那么返回上一行,改变上一行皇后的位置,再重复上述的操作。如果能够走到最后一行放置皇后,这就是一种可行的解法。而当第一行的皇后走到末尾列的时候,就是整个搜索过程的结束。

算法思想好理解,但是把它们翻译成代码,就不是那么好写的了

所需变量:

  • column:首先我们需要一个一维数组来记录已放置的皇后的位置,数组元素的下标表示行数,数组元素的值表示列数,将该数组记作column
  • row,col:当前位置是处于哪一行,哪一列
  • total:记录解法的数量
  • n:皇后的个数

步骤:

  • 辅助函数isOK(row, col):判断当前位置是否能够放置皇后,遍历已经当前行数之前的皇后,如果有皇后的列数等于当前的列数(同一列),或者行数差的绝对值等于列数差的绝对值(同一对角线),说明会冲突
    def isOk(self,row, col):
        for i in range(0, row):
            if(col == self.column[i] or abs(row - i) == abs(col - self.column[i])):
                return False
        return True
  • 主函数:首先判断当前行是否是最后一行,如果是,解法加1,如果不是,寻找当前行的合适位置,如果合适的话,进入下一行,如果不合适继续寻找。如果该行找不到合适的位置,那么当前循环结束,回退到上一行的queue循环当中
    def queue(self, row):
       if(row == self.n): 
           self.total += 1
       else:
           for col in range(0, self.n):
               self.column[row] = col 
               if(self.isOk(row, col)):
                   self.queue(row + 1)     # 进入下一行

完整代码如下:

class Solution:
    def isOk(self,row, col):
        for i in range(0, row):
            if(col == self.column[i] or abs(row - i) == abs(col - self.column[i])):
                return False
        return True

    def queue(self, row):
        if(row == self.n):
            self.total += 1
        else:
            for col in range(0, self.n):
                self.column[row] = col
                if(self.isOk(row, col)):
                    self.queue(row + 1)

    def totalNQueens(self, n: int) -> int:
        self.total = 0
        self.n = n
        self.column = [0] * self.n
        self.queue(0)
        return self.total

猜你喜欢

转载自blog.csdn.net/SJTUKK/article/details/109133521