[LeetCode] 51. N-Queens_Hard tag: DFS, backtracking

博客围绕n皇后问题展开,该问题是在n×n棋盘上放置n个皇后,使任意两个皇后不能相互攻击。可将其看成求符合特定条件的[1, 2, 3,... n]的排列,利用特定条件判断,还提及时间复杂度为O( n! * n),并给出代码转载链接。

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'and '.' both indicate a queen and an empty space respectively.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

其实我们可以看成实际上是求符合某些条件的[1, 2, 3, ... n] 的permutation[LeetCode] 47. Permutations II_Medium tag: DFS, backtracking,而条件就是要Q不在一条斜线上,利用[LeetCode] 系统刷题7_Array & numbers中的一条斜线上的条件来判断,另外有个函数来画puzzle, 会利用到''.join(strList) = 'abcd'  if strList = ['a', 'b', 'c', 'd']

时间复杂度 = 方案总数 * 构造方案所需时间

O( n ! * n)

 

Code:

class Solution:
    def nQueens(self, n):
        if n < 1: return []
        ans, nums = [], [i for i in range(1, n + 1)]
        search(ans, [], nums)
        return ans

    def search(self, ans, temp, nums):
        if not nums:
            ans.append(self.drawPuzzle(temp))
        else:
            for i in range(len(nums)):
                if self.isValid(temp, nums[i]):
                    self.search(ans, temp + [nums[i]], nums[:i] + nums[i + 1:])
    
    def isValid(self, temp, num):
        length = len(temp)
        for r, c in enumerate(temp, 1):
            if r + c == num + length + 1 or r - c == length + 1 - num:
                return False
        return True

    def drawPuzzle(self, temp):
        n = len(temp)
        puzzle = [['.'] * n for _ in range(n)]
        for r, c in enumerate(temp):
            puzzle[r][c - 1] = 'Q'
        for i in len(n):
            puzzle[i] = ''.join(puzzle[i])
        return puzzle

 

转载于:https://www.cnblogs.com/Johnsonxiong/p/10916496.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值